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> | both | Where to load from (inferred if omitted) |
--lc-json <path> | local | Path to the loader config |
--project-id <str> | remote | Console project id |
--api-key <str> | remote | API key |
--version <id> | remote | Version 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-serve | true | Auto-spawn dcupl serve to load the project |
--max-memory <MB> | — | Cap the loader's memory |
--quality <bool> | true | Run quality checks |
--limit <n> | 10 | Max 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:
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 } }
critical Property 'price' declared as number but data is string
Product.price · ModelDefinitionError / InvalidPropertyType
warning Unresolved reference 'customerId' → Customer
Order.customerId · ReferenceDataError / UnresolvedReference
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 |
|---|---|---|
| Critical | ModelDefinitionError, ResourceError | The workspace can't load or a model is malformed — blocks everything downstream. Must fix. |
| Warning | ReferenceDataError, PropertyDataError, DataContainerError | Data-level issues (stray foreign keys, type mismatches). May resolve as more data loads. |