[Canonical page](<https://docs.dhtmlx.com/planning-engine/js/api/types/errors/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Errors

Every [`Project`](<https://docs.dhtmlx.com/planning-engine/js/api/project.md>) method and [`schedule`](<https://docs.dhtmlx.com/planning-engine/js/api/schedule.md>) is synchronous and reports failure by throwing. The package exports two error classes, `InputError` and `ProjectError`; both extend `Error` and can be checked with `instanceof`. Conflicts, dependency cycles, non-convergence and rejected [`apply`](<https://docs.dhtmlx.com/planning-engine/js/api/project-apply.md>) operations are not errors: they're reported inside the result.

## InputError

Thrown when the data or options passed to a call are invalid. The project keeps its previous state.

```ts
class InputError extends Error {
  name: "InputError";
  kind: "parse" | "validation";
  message: string;
  path: string | null;
}
```

| Field | Type | Description |
|---|---|---|
| `name` | `string` | Always `"InputError"`. |
| `kind` | `"parse" \| "validation"` | `"parse"`: the input doesn't have the expected shape (wrong type, unknown key in options or a change set). `"validation"`: the shape is right, but a value isn't allowed. |
| `message` | `string` | Short description of the problem, such as `"invalid duration"`. |
| `path` | `string \| null` | Location of the offending field, such as `"tasks[0].start_date"` or `"pool.workers[1].resource"`. `null` when the error has no single field. |

`InputError` is also thrown while the input objects are read, before decoding:

| `message` | When |
|---|---|
| `"Numbers must be finite"` | A number is `NaN` or `±Infinity`. `path` is the property name only, or `null`. |
| `"Invalid Date"` | A `Date` in the input is invalid. `path` is `null`. |
| `"Unknown dates representation"` | `new Project({ dates })` got a value other than `"string"` or `"date"`. `path` is `"dates"`. |

Thrown by: [`new Project`](<https://docs.dhtmlx.com/planning-engine/js/api/project.md>), [`schedule`](<https://docs.dhtmlx.com/planning-engine/js/api/schedule.md>), [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/js/api/project-solve.md>), [`Project#preview`](<https://docs.dhtmlx.com/planning-engine/js/api/project-preview.md>), [`Project#analyze`](<https://docs.dhtmlx.com/planning-engine/js/api/project-analyze.md>), [`Project#apply`](<https://docs.dhtmlx.com/planning-engine/js/api/project-apply.md>), [`Project#level`](<https://docs.dhtmlx.com/planning-engine/js/api/project-level.md>), [`Project#loadProfile`](<https://docs.dhtmlx.com/planning-engine/js/api/project-load-profile.md>), [`Project#evaluate`](<https://docs.dhtmlx.com/planning-engine/js/api/project-evaluate.md>), [`Project#slots`](<https://docs.dhtmlx.com/planning-engine/js/api/project-slots.md>), [`Project#suggestAssignments`](<https://docs.dhtmlx.com/planning-engine/js/api/project-suggest-assignments.md>). Each operation page lists the inputs it rejects.

:::note
`new Project(options)` throws an `InputError` if an option is unknown or has an invalid value.
:::

:::note
`slots` throws `InputError` / `ProjectError` like the other `Project` methods.
:::

## ProjectError

Thrown when a call doesn't fit the project's current state. The input may be valid; the project keeps its state.

```ts
class ProjectError extends Error {
  name: "ProjectError";
  code: "no-baseline" | "stale-baseline" | "needs-resync";
  message: string;
}
```

| Field | Type | Description |
|---|---|---|
| `name` | `string` | Always `"ProjectError"`. |
| `code` | `"no-baseline" \| "stale-baseline" \| "needs-resync"` | Reason for the error; values below. |
| `message` | `string` | Same string as `code`. |

| `code` | When it occurs | Thrown by |
|---|---|---|
| `"no-baseline"` | The project has no solved baseline: it was never solved, or `apply` ran after the last solve. | [`preview`](<https://docs.dhtmlx.com/planning-engine/js/api/project-preview.md>), [`loadProfile`](<https://docs.dhtmlx.com/planning-engine/js/api/project-load-profile.md>), [`evaluate`](<https://docs.dhtmlx.com/planning-engine/js/api/project-evaluate.md>), [`slots`](<https://docs.dhtmlx.com/planning-engine/js/api/project-slots.md>), [`suggestAssignments`](<https://docs.dhtmlx.com/planning-engine/js/api/project-suggest-assignments.md>) |
| `"stale-baseline"` | A `baselineId` in the options or in [`SchedulingChanges`](<https://docs.dhtmlx.com/planning-engine/js/api/types/scheduling-changes.md>) isn't the current baseline. | [`preview`](<https://docs.dhtmlx.com/planning-engine/js/api/project-preview.md>), [`apply`](<https://docs.dhtmlx.com/planning-engine/js/api/project-apply.md>), [`loadProfile`](<https://docs.dhtmlx.com/planning-engine/js/api/project-load-profile.md>), [`evaluate`](<https://docs.dhtmlx.com/planning-engine/js/api/project-evaluate.md>), [`suggestAssignments`](<https://docs.dhtmlx.com/planning-engine/js/api/project-suggest-assignments.md>) |
| `"needs-resync"` | An earlier `apply` rejected an operation, and no full `solve(data)` has run since. | [`apply`](<https://docs.dhtmlx.com/planning-engine/js/api/project-apply.md>), [`solve(null)`](<https://docs.dhtmlx.com/planning-engine/js/api/project-solve.md>), [`level`](<https://docs.dhtmlx.com/planning-engine/js/api/project-level.md>) |

For how to recover from each code, see [Error handling](<https://docs.dhtmlx.com/planning-engine/js/error-handling.md>).

## Other errors

These are not exported classes. Check them by `name`, `message` or constructor.

| Error | When it occurs |
|---|---|
| `Error("Project has been disposed")` | Any call on a project after its `dispose()`. |
| `TypeError` | The input has a circular reference or a `BigInt`. The messages match `JSON.stringify`. |
| `Error` with `name` `"Panic"` | An internal engine assertion failed. This is a library bug. |

:::note
`dispose()` is optional; after it, every call on that project throws `Error("Project has been disposed")`.
:::

## Example

```js
import { InputError, ProjectError, schedule } from "plen-js";

try {
  schedule({ tasks: [{ id: 1, start_date: "2026-01-05 08:00", duration: -1 }] });
} catch (error) {
  if (error instanceof InputError) {
    console.error(error.kind, error.path, error.message);
  } else if (error instanceof ProjectError) {
    console.error(error.code);
  } else {
    throw error;
  }
}
```

## Related

- [`Project`](<https://docs.dhtmlx.com/planning-engine/js/api/project.md>) - the constructor options that can throw `InputError`
- [`RejectedOperation`](<https://docs.dhtmlx.com/planning-engine/js/api/types/common.md#rejectedoperation>) - refused `apply` operations, reported instead of thrown
- [Error handling](<https://docs.dhtmlx.com/planning-engine/js/error-handling.md>) - catching errors and recovering from each code
- [Recover from rejected changes](<https://docs.dhtmlx.com/planning-engine/js/how-to/recover-from-rejected-changes.md>) - handling `"needs-resync"`
- [Accept messy input](<https://docs.dhtmlx.com/planning-engine/js/how-to/accept-messy-input.md>) - `validation: "repair"` instead of strict errors
