Skip to content

Running esdm lint

This page walks through the lint workflow: what esdm lint does, what the output looks like on a clean and a broken model, how the exit code and severity levels relate, and how to wire the linter into a continuous-integration pipeline.

This page assumes you have a small model on disk. Either Your First Model with AI or Your First Model by Hand produces a fitting companion; the concrete examples below are taken from the by-hand model, since pinning the artifact and field names down makes the diagnostics easier to follow. The CLI reference documents the exact flags and arguments; this page focuses on the workflow around them.

Linting a Clean Model

From inside the directory that holds your .esdm.yaml files:

./esdm lint

A clean model produces no output and exits with status 0. Silence is success: if there is nothing wrong, the linter has nothing to say. Pipe the exit code into a script or a CI step and act on it.

./esdm lint && echo "model is clean"

To lint a directory other than the current one, pass -d (or --directory). The linter walks the directory recursively, so a project with one .esdm.yaml per consistency unit is linted in one invocation.

Reading a Finding

When the linter has something to say, it groups the output around five pieces of information per finding: the severity, the ID of the rule that threw it, the location (file, line, column), a one-line message that explains what's wrong, and a link to the rule's entry in the documentation.

For example, if the state field on book.esdm.yaml is renamed to stateOmitted, the linter reports:

error: esdm/structure/missing-required-field
  at book.esdm.yaml:1:1
  missing required field "state"
  see https://www.esdm.io/reference/linter-rules/#structure-missing-required-field

error: esdm/structure/unknown-field
  at book.esdm.yaml:11:3
  unknown field "stateOmitted"
  see https://www.esdm.io/reference/linter-rules/#structure-unknown-field

Multiple findings on the same file are reported in source order. The location format is <file>:<line>:<column>, which most editors and CI log viewers render as a clickable link. The see line points at the rule's entry on the Linter Rules page, which says what the rule checks and why; follow it when the message alone does not tell you what to change.

Severity and Exit Code

The linter classifies every finding as either an error or a warning.

An error is a structural or modeling defect serious enough to break the model: a missing required field, an unresolved reference, a forbidden combination of fields. A run with at least one error exits with a non-zero status.

A warning is a softer signal: a Read Model with no Query reading from it, an Event with no consumer, a redundant naming pattern. Warnings are reported, but they do not by themselves fail the run – a warning-only model still exits with 0. If you want warnings to fail your build too, pass --warnings-as-errors:

./esdm lint --warnings-as-errors

The flag does not change what is printed; it only escalates the exit code so a warning-only run reports a non-zero status. That is the ESDM equivalent of treating compiler warnings as errors – a deliberate choice for CI pipelines, opt-in everywhere else.

JSON Output

For tooling, editor integrations, or CI pipelines that want to parse findings rather than read them, run with --format json:

./esdm lint --format json

The output is a JSON array with one object per finding. The shape carries the same severity, location, message, and rule ID that the human format prints, plus documentationUrl, the address of the rule's entry on the Linter Rules page. Parse it, group it, or post-process it as you prefer.

Linting in CI

Lint on every push and on every pull request. The linter is fast – sub-second on a model with hundreds of artifacts – so there is no reason to gate it.

A minimal GitHub Actions step that downloads the binary and lints the model looks like this:

- name: Install ESDM
  run: |
    curl -sSL -o esdm \
      https://esdm.s3.fr-par.scw.cloud/0.15.0/esdm-linux-amd64
    chmod a+x esdm

- name: Lint ESDM model
  run: ./esdm lint --directory ./model --color never --warnings-as-errors

--color never keeps ANSI escape codes out of CI logs. --warnings-as-errors is the recommended default for CI: warnings rarely belong on a clean main branch, and the flag turns the exit code into a single binary signal. The exit code carries the success signal automatically; no extra if is needed.

Where to Go Next

  • Running esdm view complements the linter with a structural view of the model.
  • Editor Support sets up your editor so problems surface while you type, not only on a manual esdm lint run.
  • CLI: esdm lint documents every flag and the exact exit-code semantics.