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


# Violation

The bound of a task's dates that its links and its constraint disagree on. A `Violation` arrives in the `violation` field of [`Conflict::ConstraintViolation`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/conflict.md>), next to the [`ConstraintType`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/constraint-type.md>) that set the bound.

## Declaration

```rust
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Violation {
    EarliestStart,
    LatestStart,
    EarliestEnd,
    LatestEnd,
}
```

## Variants

| Variant | Description |
|---|---|
| `EarliestStart` | The links want the task to start before the earliest start its constraint allows ([`Snet`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/constraint-type.md>), `Mso`). Reported in backward scheduling. |
| `LatestStart` | The links want the task to start after the latest start its constraint allows (`Snlt`, `Mso`). Reported in forward scheduling. |
| `EarliestEnd` | The links want the task to end before the earliest end its constraint allows (`Fnet`, `Mfo`). Reported in backward scheduling. |
| `LatestEnd` | The links want the task to end after the latest end its constraint allows (`Fnlt`, `Mfo`). Reported in forward scheduling. |

What `required` and `actual` hold for each variant is described on [`Conflict`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/conflict.md>).

## Serialization

With the `serde` feature, `Violation` serializes as a kebab-case string: `"earliest-start"`, `"latest-start"`, `"earliest-end"`, `"latest-end"`. See [Serialize results to JSON](<https://docs.dhtmlx.com/planning-engine/rust/how-to/serialize-results-to-json.md>).

## Example

```rust
use plen_core::{
    Conflict, ConstraintType, DateTime, LinkData, LinkType, Project, ProjectData,
    SchedulingConfig, SolveOptions, TaskData, Violation,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let monday = DateTime::from_ymd_hm(2026, 1, 5, 8, 0).ok_or("invalid date")?;
    let tuesday = DateTime::from_ymd_hm(2026, 1, 6, 8, 0).ok_or("invalid date")?;

    let mut design = TaskData::new("design");
    design.start_date = Some(monday);
    design.duration = Some(2.0);

    // `build` must start by Tuesday, but `design` ends later.
    let mut build = TaskData::new("build");
    build.start_date = Some(monday);
    build.duration = Some(3.0);
    build.constraint_type = Some(ConstraintType::Snlt);
    build.constraint_date = Some(tuesday);

    let data = ProjectData {
        config: SchedulingConfig {
            apply_constraints: true,
            ..Default::default()
        },
        tasks: vec![design, build],
        links: vec![LinkData {
            id: "l1".into(),
            source: "design".into(),
            target: "build".into(),
            link_type: LinkType::Fs,
            lag: 0.0,
            lag_unit: None,
        }],
        ..Default::default()
    };

    let mut project = Project::default();
    let result = project.solve(Some(data), &SolveOptions::default())?;

    for conflict in &result.conflicts {
        if let Conflict::ConstraintViolation { task, violation, .. } = conflict {
            let bound = match violation {
                Violation::EarliestStart => "earliest start",
                Violation::LatestStart => "latest start",
                Violation::EarliestEnd => "earliest end",
                Violation::LatestEnd => "latest end",
            };
            println!("{task}: links cross the {bound}");
        }
    }
    Ok(())
}
```

## Related

- [`Conflict`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/conflict.md#constraintviolation>) - carries the violation
- [`ConstraintType`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/constraint-type.md>) - the constraint whose bound is violated
- [Links, constraints and summaries](<https://docs.dhtmlx.com/planning-engine/rust/scheduling/links-constraints-summaries.md#detecting-a-constraint-that-a-link-breaks>) - triggers and reads a violation
- [Reading results](<https://docs.dhtmlx.com/planning-engine/rust/scheduling/reading-results.md#conflicts>) - handles conflicts in a result
