Until now, the only way to find out whether your .cosmoner/deployment.yaml was
right was to select the repository in the deploy wizard and see what it said.
That is late — the file is already committed and pushed by then.
You can now check it wherever you write it.
From your terminal
npx @cosmoner/cli validate
Nothing to install, no API key, no account. It finds the file the same way we do, and tells you what we would make of it:
.cosmoner/deployment.yaml
2:11 error Service names must be lowercase letters, numbers, or hyphens, and start with a letter or number services.0.name
4:18 error Static sites cannot define a run_command services.0.run_command
5:11 warning Unknown field "prot" — it will be ignored services.0.prot
2 errors, 1 warning
It has nothing to do with the language your app is written in — the file describes a deployment, not a Node project — so it is as useful in a Go or Rust repository as in a JavaScript one.
In CI
--format github puts each finding on the right line of the diff:
- name: Validate deployment file
run: npx @cosmoner/cli validate --strict --format github
There is also --format json if you would rather act on the results yourself.
The command exits 1 when a file does not pass and 2 when the command itself
was wrong, so a failing check never gets confused with a typo in your workflow.
Errors and warnings
An error means we cannot deploy the file as written. A warning means we
will accept it but you probably did not mean it — an unknown key is the common
one. We ignore keys we do not recognise rather than rejecting the file, so that
a file written for a newer field still works on an older deploy; that is
deliberate, and a misspelled prot: is what it costs. The warning tells you
what will happen to it.
Add --strict when you would rather not let one through.
Tidy the file, or start one
cosmoner fmt # canonical field order, plus a $schema header for your editor
cosmoner init # a starter file with the fields you are most likely to set
fmt keeps your comments, and keeps fields we do not recognise rather than
deleting them.
The same check in the SDKs
If you generate the file, or check it as part of a deployment script, all three SDKs now expose the validator. No API key and no network call there either.
from cosmoner import validate_deployment
result = validate_deployment(source)
for issue in result.issues:
print(f"{issue.severity} {issue.path}: {issue.message}")
import { validateDeployment } from "@cosmoner/sdk";
$result = Cosmoner\Sdk\Deployment::validate($source);
Each one also hands back the file as we read it — defaults applied, unknown keys dropped — so you can see the settings that will actually arrive rather than the ones you wrote.
All four give the same answer to the same file, down to the wording and the order of the findings.
See App Configuration Files for the full format reference.