Exit codes¶
This page defines the stable CLI exit-code contract for TopMark. These codes are intended for CI, automation, subprocess orchestration, and scripting.
TopMark follows a small, consistent set of exit codes across commands, with a few command-specific semantic signals (notably for dry-run change detection and runtime-resolution status).
Exit codes define the stable command-line contract for:
- CI and release workflows integration
- shell scripting
- editor integration
- pre-commit hooks
- automation and orchestration
- machine-readable automation and subprocess orchestration
Note
The canonical vocabulary used throughout the documentation is defined in Terminology and Canonical Vocabulary.
Exit-code behavior is intentionally deterministic and stable across:
- normal CLI execution
- pre-commit execution
- CI environments
- API-driven runtime orchestration workflows
Overview¶
| Code | Name | Meaning |
|---|---|---|
| 0 | SUCCESS | Operation completed successfully. |
| 1 | FAILURE | Generic failure (non-specific error). |
| 2 | WOULD_CHANGE | Dry-run indicates changes would be made (used by check and strip without --apply). |
| 64 | USAGE_ERROR | Invalid CLI usage (invalid options, incompatible flags). |
| 65 | ENCODING_ERROR | Text decoding/encoding error (e.g., Unicode issues). |
| 66 | FILE_NOT_FOUND | Explicit input path does not exist. |
| 69 | UNSUPPORTED_FILE_TYPE | Unsupported, unresolved, filtered, or unavailable semantic outcome (primarily used by probe). |
| 70 | PIPELINE_ERROR | Internal pipeline failure or missing required processing result. |
| 74 | IO_ERROR | Read/write failure (e.g., filesystem write error). |
| 77 | PERMISSION_DENIED | Insufficient permissions (read/write). |
| 78 | CONFIG_ERROR | Runtime configuration could not be loaded, resolved, or validated for execution. |
| 100 | VERSION_CONVERSION_ERROR | Version information could not be determined or converted. |
| 255 | UNEXPECTED_ERROR | Unhandled exception fallback. |
Notes:
- Codes broadly follow sysexits-style semantics where applicable.
- Not all codes are used by every command.
- Commands may short-circuit on higher-severity errors (e.g., config errors before processing).
- Canonical file-type identifier normalization does not affect exit-code semantics.
- Ambiguous or malformed file-type identifiers are reported diagnostically and may contribute to configuration-loading or runtime-resolution outcomes depending on command behavior.
- Explicit missing literal paths are treated as hard input errors (66). Unmatched glob patterns are soft diagnostics and do not produce 66.
Exit codes vs machine-readable output¶
Exit codes and machine-readable output intentionally represent different compatibility layers.
Exit codes communicate:
- process-level runtime outcome;
- semantic change detection;
- configuration-loading status;
- runtime availability and environment failures.
Machine-readable JSON and NDJSON output communicate structured diagnostics, semantic outcomes, runtime-resolution details, and processing metadata.
This separation keeps automation deterministic while preserving stable machine-readable output contracts independently from process exit semantics.
Command-specific behavior¶
check¶
| Scenario | Exit code |
|---|---|
| No differences (clean) | 0 |
| Differences found (dry-run) | 2 |
Changes applied successfully (--apply) |
0 |
| Configuration error | 78 |
| Write failure during apply | 74 |
| CLI usage error | 64 |
| Missing explicit input | 66 |
| Unexpected or internal error | 70 / 255 |
Notes:
2is a semantic change signal, not a runtime failure: it indicates that files would change.- In CI, treat
2as "diff detected". - Explicit missing input paths are reported as errors (66), even if no files are selected for processing.
- Unmatched glob patterns are treated as discovery diagnostics and do not cause failure.
strip¶
| Scenario | Exit code |
|---|---|
| Nothing to strip / no changes | 0 |
| Changes would occur (dry-run) | 2 |
Changes applied successfully (--apply) |
0 |
| Configuration error | 78 |
| Write failure during apply | 74 |
| CLI usage error | 64 |
| Missing explicit input | 66 |
| Unexpected or internal error | 70 / 255 |
Notes:
- Explicit missing input paths are reported as errors (66).
- Unmatched glob patterns are treated as discovery diagnostics and do not cause failure.
probe¶
| Scenario | Exit code |
|---|---|
| All inputs resolved successfully | 0 |
| Any input unresolved / unsupported / filtered | 69 |
| Missing explicit input | 66 |
| Missing probe result / internal inconsistency | 70 |
| Configuration error | 78 |
| CLI usage error | 64 |
Notes:
69indicates partial, unavailable, or filtered semantic resolution, not a runtime failure.- This is useful for automation that requires full resolvability.
- Missing explicit input paths are treated as hard errors (66) and take precedence over semantic probe outcomes.
- Unmatched glob patterns are reported as filtered semantic outcomes and result in exit code 69.
- Ambiguous or unresolved file-type filtering may also contribute to semantic resolution outcomes.
config check¶
| Scenario | Exit code |
|---|---|
| Configuration is valid | 0 |
| Configuration is invalid (validation result) | 1 |
| CLI usage error | 64 |
| Internal error | 70 / 255 |
Important distinction:
- Exit code
1is not a runtime configuration-loading failure. - It indicates that configuration validation completed and found issues.
- Errors that prevent validation entirely use
78(not typically surfaced here).
config dump¶
| Scenario | Exit code |
|---|---|
| Dump successful | 0 |
| Configuration cannot be constructed | 78 |
| CLI usage error | 64 |
Notes:
- Non-fatal diagnostics do not affect the exit code.
config defaults / config init¶
| Scenario | Exit code |
|---|---|
| Successful output | 0 |
| CLI usage error | 64 |
registry filetypes / registry processors / registry bindings¶
| Scenario | Exit code |
|---|---|
| Successful output | 0 |
| CLI usage error | 64 |
Notes:
- These commands are informational-only and do not perform runtime file processing.
version¶
| Scenario | Exit code |
|---|---|
| Version displayed successfully | 0 |
| Version resolution failure | 100 |
| CLI usage error | 64 |
Notes:
- Exit code
100is rare and typically only occurs in development or broken installations.
Behavior in scripts and CI¶
Recommended handling:
- Treat
0as success. - Treat
2as non-error change signal (forcheck/strip). - Treat
1(fromconfig check) as a configuration-validation result rather than a runtime failure. - Treat
64,66,69,70,74,78,255as errors. 66indicates explicit literal input errors (e.g., missing paths), not unmatched glob patterns.
These recommendations apply equally to:
- local automation scripts
- CI pipelines
- pre-commit hooks
- editor tooling
- GitHub Actions and similar runners
Exit code priority (mixed results)¶
When multiple conditions occur during a single invocation, TopMark selects the exit code based on the highest-priority runtime outcome.
Priority order (highest to lowest):
This ordering ensures deterministic behavior even when multiple independent runtime conditions and semantic outcomes occur during a single invocation.
- Permission errors (
77) and other filesystem access failures - Missing explicit inputs (
66) - Write/apply failures (
74) - Configuration errors (
78) - Semantic/availability signals (
69) - Generic failures (
1)
This ensures that hard runtime or environment failures take precedence over informational, semantic, or availability-oriented outcomes.
Example:
# Detect formatting/header drift without applying changes
if ! topmark check . ; then
if [ $? -eq 2 ] ; then
echo "Changes required"
else
echo "Error during check"
exit 1
fi
fi
Relationship to --quiet¶
--quietdoes not affect exit codes.- It only suppresses human-readable TEXT rendering.
- Machine-readable JSON and NDJSON output preserve identical exit-code behavior.
- This ensures scripts remain reliable.
Stability guarantee¶
The exit-code contract defined on this page is part of TopMark's stable 1.x CLI compatibility surface.
Future changes will:
- preserve existing codes,
- only introduce new codes in a backward-compatible manner, or
- require a major version bump.