Exit codes & PR annotations
This page is the contract between docmeta and your pipeline: what each exit code means, what each output format looks like, and when color is emitted. If you are wiring docmeta into a gate or parsing its output, this is the reference to build against.
Exit codes
Section titled “Exit codes”docmeta validate returns one of three exit codes. Every CI platform treats a
non-zero exit as a failed step, so the gate is enforced without extra scripting.
| Code | Meaning | When it happens |
|---|---|---|
0 |
Success | Every validated file satisfies its schema set. |
1 |
Validation failures | One or more files failed validation. The run completed; the documents are non-conformant. |
2 |
Operational or usage error | docmeta could not complete the run — for example, no inputs and no config, an unknown --format, an unreadable config file, or an unexpected internal error. |
The distinction between 1 and 2 matters in a pipeline. Exit 1 is a result:
docmeta ran and found problems your authors must fix. Exit 2 is a failure of
the run itself: a misconfiguration or environment problem you must fix. A gate
that treats every non-zero exit the same will still block bad metadata, but
separating the two lets you tell “the docs are wrong” from “the check is broken.”
Output formats
Section titled “Output formats”docmeta validate supports three output formats, selected with -f / --format.
The default is pretty.
| Format | Audience | Machine-readable | Available on |
|---|---|---|---|
pretty |
Humans, local runs | No | validate, get, schemas |
json |
Dashboards, scripts, tooling | Yes | validate, get, schemas |
github |
GitHub Actions PR annotations | Yes (one line per error) | validate only |
pretty
Section titled “pretty”The default. A check mark or cross per file, indented error lines beneath each failing file, and a summary line. Intended for humans reading a terminal or a CI log.
$ docmeta validate bad-timestamp.md✗ bad-timestamp.md /timestamp must match format "date-time" (line 4) [google:okf:0.1]
1 file checked, 0 passed, 1 failed, 1 errorPassing files show as ✓ <file>. Add -q / --quiet to hide passing files and
show only failures plus the summary. The summary line reports
<n> files checked, <n> passed, <n> failed, <n> errors.
A single JSON object printed to stdout, suitable for dashboards or further
processing. The top level has a summary and a results array.
$ docmeta validate bad-timestamp.md --format json{ "summary": { "files": 1, "passed": 0, "failed": 1, "errors": 1 }, "results": [ { "file": "bad-timestamp.md", "format": "markdown", "ok": false, "schemas": ["google:okf:0.1"], "errors": [ { "schema": "google:okf:0.1", "instancePath": "/timestamp", "message": "must match format \"date-time\"", "line": 4 } ] } ]}The shape is stable:
summary— counts across the whole run.files— number of files checked.passed— files that satisfied every schema in their set.failed— files with at least one validation error.errors— total individual validation errors across all files.
results— one object per file.file— the file path as docmeta saw it.format— the extractor that read the file (for examplemarkdown).ok—truewhen the file passed every schema in its set.schemas— the schema ids the file was validated against.errors— the individual violations for this file (empty whenok).
- Each error — one schema violation.
schema— the schema id that produced the error.instancePath— a JSON Pointer to the offending field (""for the document root,"/tags/0"for the first item oftags).message— the human-readable reason.line— 1-based source line, when docmeta can locate it. Omitted when unknown — for example, errors at the document root often have no specific line.col— 1-based column. This field is defined in the output contract and is emitted when present, but the current extractors resolve errors to a line only, socolis absent in practice today. Treat it as optional.
github
Section titled “github”One GitHub Actions workflow command per error. GitHub renders each line as an annotation pinned to the file and line in the pull request diff. There is no summary line and no per-file heading — only error lines, one per violation. A passing run prints nothing.
The format of each line is:
::error file=<file>,line=<line>,col=<col>::[<schema>] <field> <message>file=is always present.line=is included only when the error has a known line.col=is included only when the error has a known column. Current extractors resolve to a line only, socol=is absent in practice today.<schema>is the schema id that produced the error.<field>is the JSON Pointer to the offending field, or(root)when the error is at the document root.<message>is the human-readable reason.
A concrete line — a malformed timestamp field that fails the date-time
format:
::error file=bad-timestamp.md,line=4::[google:okf:0.1] /timestamp must match format "date-time"When the line is unknown, line= is dropped and only file= remains. A
required-property error at the document root reports the field as (root):
::error file=missing-type.md::[google:okf:0.1] (root) must have required property 'type'Color and TTY behavior
Section titled “Color and TTY behavior”docmeta follows clig.dev conventions: primary output goes to
stdout, diagnostics go to stderr, and color is emitted only when it is safe to do
so. Color affects only the pretty format — json and github are always plain
text so they parse reliably.
docmeta decides whether to emit ANSI color like this, in order:
--no-color— passing this flag disables color unconditionally.NO_COLOR— if theNO_COLORenvironment variable is set to any non-empty value, color is disabled.- TTY detection — otherwise, color is emitted only when stdout is an interactive terminal (a TTY).
In practice this means color turns off automatically in CI, because a piped or
redirected stream is not a TTY. You rarely need --no-color in a pipeline, but
it is available when you want to force plain output — for example, when capturing
a log that a downstream tool will read.