[Canonical page](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# ScheduleResult

The output of one scheduling call: the tasks that changed, plus the cycles, conflicts and notes found on the way. [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>), [`Project#preview`](<https://docs.dhtmlx.com/planning-engine/java/api/project-preview.md>), [`Project#analyze`](<https://docs.dhtmlx.com/planning-engine/java/api/project-analyze.md>) and [`Engine.schedule`](<https://docs.dhtmlx.com/planning-engine/java/api/engine-schedule.md>) return one. [`Project#level`](<https://docs.dhtmlx.com/planning-engine/java/api/project-level.md>) returns one in [`LevelingResult.schedule`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/leveling-result.md#schedule>). Cycles, conflicts and non-convergence are reported here as data, not thrown.

## Declaration

```java
package org.dhtmlx.plen;

public class ScheduleResult extends ValueRecord implements DeepCloneable<ScheduleResult> {
  public String baselineId = null;
  public Vec<Mutation> updates = new Vec<Mutation>();
  public Vec<Cycle> cycles = new Vec<Cycle>();
  public Vec<Conflict> conflicts = new Vec<Conflict>();
  public Vec<Note> notes = new Vec<Note>();
  public boolean converged = false;
  public Analytics analytics = null;
  public Vec<ResourceOverallocation> overallocations = null;
  public LoadProfile profile = null;

  public String acceptedId();
  public ScheduleResult deepClone();
  public ScheduleResult copy();
}
```

Each field has a fluent `withX(value)` setter, and each `Vec` field also has a `withX(java.util.Collection<? extends T>)` overload. [`ValueRecord`](<https://docs.dhtmlx.com/planning-engine/java/api/support/value-record.md>) gives the class structural `equals` / `hashCode` over all fields and a readable `toString()`.

A `ScheduleResult` is read-only by contract. The project keeps the result of [`solve`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>) and [`level`](<https://docs.dhtmlx.com/planning-engine/java/api/project-level.md>) as its baseline, returns the same object from an unchanged re-solve, shares it with its copies, and reads it in [`evaluate`](<https://docs.dhtmlx.com/planning-engine/java/api/project-evaluate.md>) and [`suggestAssignments`](<https://docs.dhtmlx.com/planning-engine/java/api/project-suggest-assignments.md>). Call [`deepClone()`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md#deepclone>) before changing one.

## Fields

| Field | Type | Description |
|---|---|---|
| `baselineId` | `String` | Token of the baseline this result produced or read. `null` when there is none. |
| `updates` | [`Vec`](<https://docs.dhtmlx.com/planning-engine/java/api/support/vec.md>)`<`[`Mutation`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md>)`>` | Tasks with new dates or fields. Only changed tasks unless [`includeUnchanged`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md#includeunchanged>) is set. |
| `cycles` | `Vec<`[`Cycle`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md#cycle>)`>` | Every unique dependency cycle in the project. Empty for an acyclic project. |
| `conflicts` | `Vec<`[`Conflict`](<https://docs.dhtmlx.com/planning-engine/java/api/results/conflict.md>)`>` | Constraint violations and calendar conflicts. |
| `notes` | `Vec<`[`Note`](<https://docs.dhtmlx.com/planning-engine/java/api/results/note.md>)`>` | Non-fatal input notes: dropped links, tasks and assignments, and repairs. |
| `converged` | `boolean` | `true` when the planner reached a fixed point within the iteration limit. |
| `analytics` | [`Analytics`](<https://docs.dhtmlx.com/planning-engine/java/api/results/analytics.md>) | Critical path and slack. `null` unless the call's options request them. |
| `overallocations` | `Vec<`[`ResourceOverallocation`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/resource-overallocation.md>)`>` | Overallocated resources. `null` when the project has no assignments. |
| `profile` | [`LoadProfile`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/load-profile.md>) | Resource load of the previewed dates. Set only by [`Project#preview`](<https://docs.dhtmlx.com/planning-engine/java/api/project-preview.md>) with a `profile` query. |

### baselineId

```java
public String baselineId = null;
```

The opaque token of the accepted baseline:

- [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>) and [`Project#level`](<https://docs.dhtmlx.com/planning-engine/java/api/project-level.md>) set the baseline they accepted.
- [`Project#preview`](<https://docs.dhtmlx.com/planning-engine/java/api/project-preview.md>) sets the baseline it read.
- [`Project#analyze`](<https://docs.dhtmlx.com/planning-engine/java/api/project-analyze.md>) sets it only when called with `null` data on a solved project without unsolved edits.
- Otherwise it's `null`.

Pass the token as `baselineId` in options and change sets to detect a stale baseline. Tokens are unique per process: don't store them or compare them across runs. With `includeUnchanged`, the extra entries in `updates` don't change the token. [`acceptedId()`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md#acceptedid>) reads the field and throws when it's `null`.

### updates

```java
public Vec<Mutation> updates = new Vec<Mutation>();
```

One [`Mutation`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md>) per reported task, carrying only the fields that changed. With [`SolveOptions.includeUnchanged`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md#includeunchanged>), every scheduled task is reported. `updates` is empty when:

- `cycles` isn't empty and `includeUnchanged` is `false`, because a cyclic project keeps its dates
- the result comes from `analyze`, which doesn't schedule

What the entries are relative to depends on the call; see [`Project#preview`](<https://docs.dhtmlx.com/planning-engine/java/api/project-preview.md>) and [`Project#level`](<https://docs.dhtmlx.com/planning-engine/java/api/project-level.md>).

### cycles

```java
public Vec<Cycle> cycles = new Vec<Cycle>();
```

One [`Cycle`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md#cycle>) per unique simple dependency cycle. Rotations of the same cycle are reported once. Two cycles that differ only in a parallel link are reported separately. Detection includes fixed and completed tasks and summary containment. When the list isn't empty, the call leaves all dates unchanged.

The number of cycles can grow exponentially in a densely cyclic graph.

### conflicts

```java
public Vec<Conflict> conflicts = new Vec<Conflict>();
```

Constraint violations and calendar conflicts found by the planner. Always empty from `analyze`. The subclasses are on the [`Conflict`](<https://docs.dhtmlx.com/planning-engine/java/api/results/conflict.md>) page.

### notes

```java
public Vec<Note> notes = new Vec<Note>();
```

Input the engine ignored or fixed instead of rejecting. The subclasses are on the [`Note`](<https://docs.dhtmlx.com/planning-engine/java/api/results/note.md>) page.

### converged

```java
public boolean converged = false;
```

`false` when the planner stopped at [`SchedulingConfig.maxIterations`](<https://docs.dhtmlx.com/planning-engine/java/api/data/scheduling-config.md#maxiterations>) before its dates settled. The result is still valid. Always `true` from `analyze`.

### analytics

```java
public Analytics analytics = null;
```

`null` when neither `slack` nor `criticalPath` is set in the call's [`AnalyticsOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/analytics-options.md>). Otherwise an [`Analytics`](<https://docs.dhtmlx.com/planning-engine/java/api/results/analytics.md>) value. Check its `status` before reading the data.

### overallocations

```java
public Vec<ResourceOverallocation> overallocations = null;
```

`null` when the project has no assignments. Otherwise one [`ResourceOverallocation`](<https://docs.dhtmlx.com/planning-engine/java/api/resources/resource-overallocation.md>) per overallocated resource. The list is empty when no resource is overallocated. Windows carry a `reason` only in a result from `level`.

### profile

```java
public LoadProfile profile = null;
```

Set only by [`Project#preview`](<https://docs.dhtmlx.com/planning-engine/java/api/project-preview.md>) when [`PreviewOptions.profile`](<https://docs.dhtmlx.com/planning-engine/java/api/project/preview-options.md#profile>) is set. `null` otherwise. To read the load of the solved baseline, call [`Project#loadProfile`](<https://docs.dhtmlx.com/planning-engine/java/api/project-load-profile.md>).

## Methods

### acceptedId

```java
public String acceptedId()
```

Returns `baselineId`. Use it where the result must carry a baseline, such as the result of `solve` or `level`.

**Returns** - the baseline token.

**Errors** - throws `IllegalStateException` when `baselineId` is `null`.

### deepClone

```java
public ScheduleResult deepClone()
```

Returns a copy with new lists and new `Mutation`, `Cycle`, `Analytics`, `ResourceOverallocation` and `LoadProfile` objects. The `Conflict` and `Note` entries are shared with the original. Use it before changing a result.

### copy

```java
public ScheduleResult copy()
```

Returns a shallow copy: the fields are copied, the lists and nested objects are shared with the original.

## Cycle

One dependency cycle: the tasks and links that form it.

```java
public class Cycle extends ValueRecord implements DeepCloneable<Cycle> {
  public Vec<Id> tasks = new Vec<Id>();
  public Vec<Id> links = new Vec<Id>();

  public Cycle deepClone();
  public Cycle copy();
}
```

| Field | Type | Description |
|---|---|---|
| `tasks` | `Vec<`[`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>)`>` | Ids of the tasks on the cycle. |
| `links` | `Vec<`[`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>)`>` | Ids of the links on the cycle. |

`Cycle` has `withTasks` / `withLinks` setters, structural `equals` / `hashCode`, `toString()`, `deepClone()` and `copy()`, like `ScheduleResult`.

## Example

Solve a project with a dependency cycle and read the result:

```java
import java.util.List;
import org.dhtmlx.plen.*;

public class ReadScheduleResult {
  public static void main(String[] args) throws Exception {
    Moment monday = Moment.fromYmdHm(2026, 1, 5, 8, 0);

    ProjectData data = new ProjectData()
        .withTasks(List.of(
            new TaskData(Id.str("a")).withStartDate(monday).withDuration(2.0),
            new TaskData(Id.str("b")).withStartDate(monday).withDuration(3.0)))
        .withLinks(List.of(
            new LinkData().withId(Id.str("l1")).withSource(Id.str("a")).withTarget(Id.str("b")),
            new LinkData().withId(Id.str("l2")).withSource(Id.str("b")).withTarget(Id.str("a"))));

    ScheduleResult result = new Project().solve(data, new SolveOptions());

    for (Cycle cycle : result.cycles) {
      System.out.println("cycle: tasks " + cycle.tasks + "; links " + cycle.links);
    }

    System.out.println("updates: " + result.updates.size() + ", converged: " + result.converged);

    for (Mutation update : result.updates) {
      System.out.println(update.id + ": " + update.startDate + " - " + update.endDate);
    }
  }
}
```

## Related

- [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>) - the main call that returns a result
- [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md>) - options that shape the result
- [`Mutation`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md>) - one entry of `updates`
- [Reading results](<https://docs.dhtmlx.com/planning-engine/java/scheduling/reading-results.md>) - how a result is organized
- [Error handling](<https://docs.dhtmlx.com/planning-engine/java/error-handling.md#results-that-are-not-errors>) - cycles, conflicts and notes as data
