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


# JsonProject.solve

Schedules a [`JsonProject`](<https://docs.dhtmlx.com/planning-engine/wasm/api/json-project.md>) and accepts the scheduled dates as its baseline. Pass project data to load a project, or `null` / `undefined` to reschedule after [`apply`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-apply.md>). [`preview`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-preview.md>), [`loadProfile`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-load-profile.md>), [`evaluate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-evaluate.md>), [`slots`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-slots.md>) and [`suggestAssignments`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-suggest-assignments.md>) need a solved project.

For a one-shot run without a handle, use [`schedule`](<https://docs.dhtmlx.com/planning-engine/wasm/api/schedule.md>).

## Signature

```ts
solve(data_json: string | null | undefined, options_json: string): string
```

Synchronous. Changes the project's state.

## Request

| Argument | Payload | Required | Description |
|---|---|---|---|
| `data_json` | [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/project-data.md>) | no | Replacement data. `null` or `undefined` schedules the current state |
| `options_json` | [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/solve-options.md>) | yes | Subtree, analytics and reporting switches. `"{}"` for defaults |

## Behavior

- With data: validates the replacement data, installs it, schedules it and accepts the result. The previous data is discarded. How the data is validated or repaired depends on the `validation` option the handle was [created](<https://docs.dhtmlx.com/planning-engine/wasm/api/json-project.md#creating>) with.
- Without data: schedules the current state when it has unsolved edits. When the project is already solved with equal options, it returns the cached result without scheduling again. The cache key is the whole options object.

Tasks touched by successful [`apply`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-apply.md>) calls since the last solve appear in `updates` as direct updates, even when the planner leaves them where the edit put them. A cyclic project returns unchanged dates and keeps those tasks pending.

`baselineId` in the result names the accepted baseline. It changes only when the data or the dates change, so solving an unchanged state keeps it.

## Response

A success [envelope](<https://docs.dhtmlx.com/planning-engine/wasm/wire-format.md#envelope>) with a [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/schedule-result.md>).

## Errors

| `kind` | `code` | When |
|---|---|---|
| `parse` | `null` | `data_json` or `options_json` isn't valid JSON, misses a required field, or has an unknown field where one is rejected (for example an unknown option) |
| `validation` | `null` | The supplied data fails validation; `path` names the field when the engine found the problem |
| `project` | `needs-resync` | No data after an `apply` rejected an operation, and no `solve` with data has followed |

After a `parse` or `validation` error the previous state and cached result are kept. Calling `solve` on a freed handle throws at host level; see [Wire format](<https://docs.dhtmlx.com/planning-engine/wasm/wire-format.md#host-level-failures>).

## Example

Load a project, commit an edit and reschedule it, in Node:

```js
const { JsonProject } = require("./pkg-node/plen_wasm.js");

const data = {
  config: { use_calendars: false },
  tasks: [
    { id: "a", start_date: "2026-08-10 08:00", duration: 2 },
    { id: "b", start_date: "2026-08-10 08:00", duration: 1 },
  ],
  links: [{ id: "ab", source: "a", target: "b" }],
};

const project = new JsonProject("{}");
try {
  const loaded = JSON.parse(project.solve(JSON.stringify(data), "{}"));
  if (!loaded.ok) throw new Error(loaded.error.message);

  // Nothing changed: the cached result comes back with the same token.
  const again = JSON.parse(project.solve(undefined, "{}"));
  console.log(again.result.baselineId === loaded.result.baselineId); // true

  project.apply(JSON.stringify({ tasks: { update: [{ id: "a", duration: 3 }] } }));

  const envelope = JSON.parse(project.solve(undefined, "{}"));
  if (envelope.ok) {
    for (const u of envelope.result.updates) {
      console.log(u.id, u.start_date, u.end_date);
    }
  } else {
    console.error(envelope.error.kind, envelope.error.code, envelope.error.message);
  }
} finally {
  project.free();
}
```

`data_json` for the first call:

```json
{
  "config": { "use_calendars": false },
  "tasks": [
    { "id": "a", "start_date": "2026-08-10 08:00", "duration": 2 },
    { "id": "b", "start_date": "2026-08-10 08:00", "duration": 1 }
  ],
  "links": [{ "id": "ab", "source": "a", "target": "b" }]
}
```

Response of the first call (only the moved task is listed):

```json
{
  "ok": true,
  "result": {
    "baselineId": "<opaque token>",
    "conflicts": [],
    "converged": true,
    "cycles": [],
    "notes": [],
    "updates": [
      { "id": "b", "kind": "task", "start_date": "2026-08-12 08:00", "end_date": "2026-08-13 08:00" }
    ]
  }
}
```

Response of the last call, after the edit to `a`:

```json
{
  "ok": true,
  "result": {
    "baselineId": "<new opaque token>",
    "conflicts": [],
    "converged": true,
    "cycles": [],
    "notes": [],
    "updates": [
      { "id": "a", "kind": "task", "start_date": "2026-08-10 08:00", "end_date": "2026-08-13 08:00", "duration": 3 },
      { "id": "b", "kind": "task", "start_date": "2026-08-13 08:00", "end_date": "2026-08-14 08:00" }
    ]
  }
}
```

## Related

- [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/project-data.md>) - the data to load
- [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/solve-options.md>) - subtree, analytics and reporting switches
- [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/schedule-result.md>) - the result payload
- [`JsonProject.apply`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-apply.md>) - commit edits for the next solve to schedule
- [Scheduling a Project](<https://docs.dhtmlx.com/planning-engine/wasm/scheduling/scheduling-a-project.md>) - loading and rescheduling a project
