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


# Conflict

A scheduling conflict found while placing tasks. Instances come from [`ScheduleResult.conflicts`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md#conflicts>), which lists every conflict of the run. A conflict is data in the result, not an exception. The run still succeeds and returns dates.

## Declaration

```java
package org.dhtmlx.plen;

public abstract class Conflict extends ValueRecord {
  public static class ConstraintViolation extends Conflict { /* ... */ }
  public static class CalendarNonWorking extends Conflict { /* ... */ }
}
```

The library creates only these two nested subclasses. Read them with `instanceof` patterns or `switch` pattern matching. The hierarchy isn't sealed, so a `switch` over a `Conflict` needs a `default` arm.

Code refers to the variant as `Conflict.ConstraintViolation`. The package also has a top-level enum `org.dhtmlx.plen.ConstraintViolation`, and with `import org.dhtmlx.plen.*;` the bare name `ConstraintViolation` refers to that enum.

## Variants

| Variant | When it occurs |
|---|---|
| `Conflict.ConstraintViolation` | A task's constraint placed it at a date its driving dependency link doesn't allow. The constraint wins, and the task keeps the constraint's date. Reported only when [`SchedulingConfig.applyConstraints`](<https://docs.dhtmlx.com/planning-engine/java/api/data/scheduling-config.md#applyconstraints>) is `true`. |
| `Conflict.CalendarNonWorking` | A summary moved as one block, and a descendant task landed on non-working time of its calendar. Reported only when [`SchedulingConfig.strictCalendar`](<https://docs.dhtmlx.com/planning-engine/java/api/data/scheduling-config.md#strictcalendar>) is `true`. |

### ConstraintViolation

```java
public ConstraintViolation(
    Id task, ConstraintType constraint, Violation violation, Moment required, Moment actual)
```

| Field | Type | Description |
|---|---|---|
| `task` | [`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>) | The task or summary whose constraint won. |
| `constraint` | [`ConstraintType`](<https://docs.dhtmlx.com/planning-engine/java/api/data/task-data.md#constrainttype>) | The constraint that placed the task: the task's own, or one inherited from a summary. |
| `violation` | [`Violation`](<https://docs.dhtmlx.com/planning-engine/java/api/results/conflict.md#violation>) | Which bound the link contradicts. |
| `required` | [`Moment`](<https://docs.dhtmlx.com/planning-engine/java/api/data/moment.md>) | The date the constraint gave the task. The task has this date in the result. |
| `actual` | [`Moment`](<https://docs.dhtmlx.com/planning-engine/java/api/data/moment.md>) | The date the driving link would have given the task. |

### CalendarNonWorking

```java
public CalendarNonWorking(Id task, Moment proposed, Moment snapped)
```

| Field | Type | Description |
|---|---|---|
| `task` | [`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>) | The descendant task that landed on non-working time. |
| `proposed` | [`Moment`](<https://docs.dhtmlx.com/planning-engine/java/api/data/moment.md>) | The task's new start, or its new end when the project is scheduled from the end. The date is on non-working time. |
| `snapped` | [`Moment`](<https://docs.dhtmlx.com/planning-engine/java/api/data/moment.md>) | The date the task keeps. Currently it's always equal to `proposed`: the task isn't moved to working time. |

## Methods

### copy

```java
public Conflict copy()
```

Returns a shallow copy. Each subclass overrides it with its own return type, such as `Conflict.ConstraintViolation copy()`. All fields are immutable values, so the copy is independent of the original.

**Returns**: a new instance of the same variant.

### equals, hashCode, toString

```java
public boolean equals(Object other)
public int hashCode()
public String toString()
```

Inherited from [`ValueRecord`](<https://docs.dhtmlx.com/planning-engine/java/api/support/value-record.md>). Two conflicts are equal when they're the same variant and all their fields are equal. `toString()` prints the variant and its fields, e.g. `ConstraintViolation{task=demo, constraint=SNLT, violation=LATEST_START, required=2026-03-03 00:00, actual=2026-03-05 00:00}`.

## Violation

Which bound of a constraint the driving link contradicts, in [`Conflict.ConstraintViolation.violation`](<https://docs.dhtmlx.com/planning-engine/java/api/results/conflict.md#constraintviolation>). `EARLIEST_START` and `LATEST_START` compare start dates. `EARLIEST_END` and `LATEST_END` compare end dates.

```java
package org.dhtmlx.plen;

public enum Violation {
  EARLIEST_START,
  LATEST_START,
  EARLIEST_END,
  LATEST_END
}
```

| Value | Description |
|---|---|
| `EARLIEST_START` | The link wants an earlier start than the constraint allows. |
| `LATEST_START` | The link wants a later start than the constraint allows. |
| `EARLIEST_END` | The link wants an earlier end than the constraint allows. |
| `LATEST_END` | The link wants a later end than the constraint allows. |

## Example

`demo` must start no later than Tuesday, but its predecessor `build` ends on Wednesday. The constraint wins, and the result reports the conflict:

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

public class ConflictExample {
  public static void main(String[] args) throws Exception {
    Moment monday = Moment.fromYmdHm(2026, 3, 2, 0, 0);
    Moment tuesday = Moment.fromYmdHm(2026, 3, 3, 0, 0);

    ProjectData data = new ProjectData()
        .withConfig(new SchedulingConfig().withApplyConstraints(true))
        .withTasks(List.of(
            new TaskData(Id.str("build")).withStartDate(monday).withDuration(3.0),
            new TaskData(Id.str("demo"))
                .withStartDate(tuesday)
                .withDuration(1.0)
                .withConstraintType(ConstraintType.SNLT)
                .withConstraintDate(tuesday)))
        .withLinks(List.of(
            new LinkData().withId(Id.num(1)).withSource(Id.str("build")).withTarget(Id.str("demo"))));

    ScheduleResult result = Engine.schedule(data, new SolveOptions());

    for (Conflict conflict : result.conflicts) {
      String text = switch (conflict) {
        case Conflict.ConstraintViolation v -> v.task + ": " + v.constraint + " " + v.violation
            + ", constraint gives " + v.required + ", link wants " + v.actual;
        case Conflict.CalendarNonWorking n -> n.task + ": on non-working time at " + n.proposed;
        default -> throw new IllegalStateException("unknown conflict: " + conflict);
      };
      System.out.println(text);
    }
  }
}
```

Output:

```
demo: SNLT LATEST_START, constraint gives 2026-03-03 00:00, link wants 2026-03-05 00:00
```

The `default` arm is there only because the compiler requires it. The library returns no other variant.

## Related

- [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md>) - the result that lists conflicts
- [`SchedulingConfig`](<https://docs.dhtmlx.com/planning-engine/java/api/data/scheduling-config.md>) - `applyConstraints` and `strictCalendar`
- [`TaskData`](<https://docs.dhtmlx.com/planning-engine/java/api/data/task-data.md#constrainttype>) - constraint types
- [Links, constraints and summaries](<https://docs.dhtmlx.com/planning-engine/java/scheduling/links-constraints-summaries.md#detecting-a-constraint-that-a-link-breaks>) - detecting a constraint that a link breaks
- [Reading results](<https://docs.dhtmlx.com/planning-engine/java/scheduling/reading-results.md#conflicts>) - reading conflicts from a result
