Skip to main content

validate

cotctl validate checks your YAML before you deploy it. Getting into the habit of validating first is one of the highest-value things you can do as a partner: it catches mistakes on your machine, in seconds, instead of as a half-applied change in a customer's environment.

There are three things you might want to validate, and validate has a mode for each:

ModeFlagNetworkWhat it's for
File-f <file>OfflineCheck a single YAML file of any supported kind
Directory--dir <path>OfflineCross-check a whole folder of resources before apply --dir
Workflow--workflow <nameCode>OnlineRun the production-readiness checklist against a live workflow

File mode — one file, offline

The quickest check. It validates a single YAML file against the schema for its kind, with no API call:

cotctl validate -f my-survey.yaml
✓ my-survey.yaml is valid

If something's wrong, it tells you what and where:

✗ my-survey.yaml has validation errors:

- code: code must start with a lowercase letter and contain only lowercase letters, numbers, and underscores

File mode isn't survey-only. It reads the kind field and runs the matching schema, so it validates any of the seven kinds apply supports — Survey, AccessRole, PropertyType, Property, JobTitle, Workflow, User. (A file with no kind is treated as a Survey, for backward compatibility.)

A single file can hold several documents separated by ---. validate checks each one and accumulates the errors — it doesn't stop at the first bad document — then reports a per-kind tally like 2 Survey documents, 1 User document validated successfully, so you can fix everything in one pass.

Under the hood, up to three layers of checking run — but only the first applies to every kind:

LayerWhat it checksApplies toHow to skip
Structure (Zod)Types, required fields, enumsAll kindsAlways on
Semanticfunction run() in exec hooks, buttons in the wrong stage, deprecated fieldsSurvey only--skip-semantic-validation
RemoteIdentifier uniqueness across the company, that referenced entities existSurvey onlyNeeds --remote + -c <profile>

Non-Survey kinds get the structural (Zod) layer only. The semantic and remote layers are Survey-specific. Remote checks reach the API, so they require a profile — and --remote can't be combined with --dir:

cotctl validate -f my-survey.yaml --remote -c acme

Directory mode — a whole folder, offline

This is the one you'll use most when working with scaffolded workflows. It validates every YAML file in a folder and checks that they reference each other correctly — all offline. Run it right before apply --dir:

cotctl validate --dir ordenes-compra/

It runs two families of checks. Schema checks, per file:

IDCheck
S1File parses as valid YAML
S2kind is present and recognized
S3Document validates against the schema for its kind

And cross-reference checks, across files — this is what catches a property pointing at a property type that doesn't exist:

IDSeverityCheck
X1warnPermission strings (name:action) are defined as AccessRoles
X2failProperty.propertyType references an existing PropertyType
X3failWorkflow state machine propertyType references resolve
X4failWorkflow states[].property references an existing Property
X5failThe state machine initialState references an existing Property
X6warnWorkflow permissions are defined as AccessRoles

A clean run ends with a clear verdict:

Results: 11 PASS, 0 WARN, 0 FAIL — ready to apply

Add --json if you want to consume the result in a script.

Workflow mode — production readiness, online

Once a workflow is live, this mode runs the Marcha Blanca (go-live) checklist against it. It's an online check, so it needs a profile:

cotctl validate --workflow ordenes_compra -c prod

The checklist is organized in three sections, and you can run just one with --section:

  • Nomenclature (nomenclature) — naming conventions for codes, forms, properties, and permissions.
  • Permissions (permissions) — that a Manager role exists with all flow permissions, wired into the linked forms.
  • Configuration (configuration) — technical rules, like control fields being read-only and an error state existing.
# only the naming checks
cotctl validate --workflow ordenes_compra --section nomenclature -c prod
Results: 13 PASS, 1 WARN, 0 FAIL — production ready

Checks are graded WARN (a recommendation) or FAIL (a real problem). The command exits 0 when everything passes or only warns, and 1 when at least one check fails — which is exactly what you want as a gate in a pipeline.

A couple of known limits. Deep JavaScript code-quality checks on exec hooks aren't implemented, and the error-state check (T3) looks for the _estado_error naming convention — if your implementation names its error state differently, expect a warning even when an error state exists.

See also

  • apply — deploy your resources once validation passes
  • scaffolding — generate a workflow skeleton to validate and apply