CLI

Validating a Project

dcupl validate is a one-shot health check. It loads a project, classifies any errors it hits, and reports empty or auto-generated models — without starting a long-running daemon. Run it locally against your working files or remotely against a Console version before you push, deploy, or merge.

Validating remotely? The --source remote mode loads a Console version, so it needs project credentials. Pass --project-id / --api-key inline, or configure them once with dcupl config set (see Cloud Sync). Local validation needs no credentials.

Choosing a source

--source selects where the project is loaded from. If you omit it, the CLI infers the source from the flags you pass.

Flag Source Purpose
--source <local|remote>bothWhere to load from (inferred if omitted)
--lc-json <path>localPath to the loader config
--project-id <str>remoteConsole project id
--api-key <str>remoteAPI key
--version <id>remoteVersion to load

Processing & performance

Shape how the project is built — apply an application, environments, tags, and variables — and bound the loader's resources.

Processing

Flag Purpose
--app-key <str>Application key to load
--env <key>Environment to apply (repeatable)
--tag <tag>Tag filter (repeatable; comma-separate for AND)
--var <KEY=VALUE>Loader variable (repeatable)

Performance

Flag Default Purpose
--auto-servetrueAuto-spawn dcupl serve to load the project
--max-memory <MB>Cap the loader's memory
--quality <bool>trueRun quality checks
--limit <n>10Max error records in the report

Reading the report

validate exits 0 even when validation failed — it runs in report mode. Do not rely on the exit code. Parse the JSON and check the top-level ok (or summary.critical) instead. Infrastructure failures are the exception — they both report and exit non-zero.

Emit machine-readable output with --json:

zsh — dcupl validate

one-shot health check, machine-readable: dcupl validate --json — output: { "ok": false, "load": { "ok": true }, "models": { "total": 12, "empty": ["Review"], "autoGenerated": ["OrderLine"] }, "errors": { "total": 2, "bySeverity": { "critical": 1, "warning": 1 }, "records": [ { "model": "Product", "attribute": "price", "errorGroup": "ModelDefinitionError", "title": "..." } ] }, "summary": { "critical": 1, "warnings": 1 } }

✗ ok: false12 models · load ok
1 critical1 warning
  • critical

    Property 'price' declared as number but data is string

    Product.price · ModelDefinitionError / InvalidPropertyType

  • warning

    Unresolved reference 'customerId' → Customer

    Order.customerId · ReferenceDataError / UnresolvedReference

Models:empty · Reviewauto-generated · OrderLine

The same report, decoded — errors.records[] with severity, plus the empty and auto-generated model signals.

Gate a script on the top-level ok, or on the critical count when warnings shouldn't block:

Error severity

Each record carries an errorGroup, errorType, model, attribute, and title. Groups roll up into two severities.

Severity Error groups Meaning
CriticalModelDefinitionError, ResourceErrorThe workspace can't load or a model is malformed — blocks everything downstream. Must fix.
WarningReferenceDataError, PropertyDataError, DataContainerErrorData-level issues (stray foreign keys, type mismatches). May resolve as more data loads.