CLI Exit Codes¶
This is the authoritative, per-command map of the process exit codes the
bvlos-sim CLI can return. The exit-code semantics are a public contract (see
VERSIONING_POLICY.md); their meanings do not change
within a published version.
A long-running caller (such as a Mission Control worker) branches on the exit code, so it must not assume one command's convention holds for another. The divergences below are intentional and are called out explicitly.
Code meanings¶
| Code | Name | Meaning |
|---|---|---|
0 |
SUCCESS |
The command completed. A feasibility verdict, if any, is in the body. |
10 |
INFEASIBLE |
A feasibility-class NO-GO outcome (e.g. estimate reports infeasible). |
11 |
INVALID_INPUT |
Input files, arguments, or referenced assets failed to load or validate. |
12 |
UNSUPPORTED |
The requested computation is not supported for these inputs. |
13 |
INTERNAL_ERROR |
An output could not be written, or an unexpected error occurred. |
14 |
CANCELLED |
The run received SIGTERM/SIGINT and aborted; no output was written. |
Every command returns 13 rather than a bare traceback (shell status 1) when
an unexpected exception escapes. A shell status 2 comes from the argument
parser (Typer/Click) for malformed invocations (unknown option, missing
argument); it is not one of the codes above.
Cancellation contract¶
Any command may receive SIGTERM or SIGINT (e.g. a worker cancelling a job or
enforcing a timeout). When it does:
- The process exits
14(CANCELLED) instead of the shell defaults (143forSIGTERM,130forSIGINT), so a caller can branch on a defined code. - No
--outputfile is left in a partial state. All on-disk writes go through an atomic temp-file-then-os.replace, so an interrupted run leaves the destination either at its prior content or absent — never truncated. A consumer can therefore trust that any file that exists is complete.
The CANCELLED code is only installed by the console-script entrypoint
(main:main); importing the Typer app in-process (as the test runner does) keeps
Python's default KeyboardInterrupt behaviour.
Per-command exit codes¶
| Command | 0 |
10 |
11 |
12 |
13 |
Notes |
|---|---|---|---|---|---|---|
estimate |
✓ | ✓ | ✓ | ✓ | ✓ | Full feasibility surface. 11 can also be a computed FailureKind.INVALID_INPUT (see divergences). |
scenario |
✓ | ✓ | ✓ | ✓ | No 12: every non-PASSED outcome collapses to 10 (divergence). |
|
sample |
✓ | ✓ | ✓ | Never 10: an infeasible Monte Carlo result is in the body, exit is 0 (divergence). |
||
propagate |
✓ | ✓ | ✓ | Never 10: an infeasible stochastic result is in the body, exit is 0 (divergence). |
||
size-battery |
✓ | ✓ | ✓ | A NO answer (no feasible capacity) is in the body, not via 10. |
||
sora |
✓ | ✓ | ✓ | SAIL / risk verdict is in the body, not via 10. |
||
validate |
✓ | ✓ | ✓ | Comparison metrics are in the body; a poor match is not 10. |
||
calibrate |
✓ | ✓ | ✓ | Fitted profile is in the body. | ||
compare |
✓ | ✓ | ✓ | ✓ | ✓ | SITL drift/fail maps to 10; unsupported comparison maps to 12. |
batch |
✓ | ✓ | ✓ | ✓ | 10 if any run is infeasible; 11 if any run failed to load. No 12. |
|
export |
✓ | ✓ | ✓ | Mission load / exportability failures are 11. |
||
convert |
✓ | ✓ | ✓ | A missing/blank --vehicle-profile and parse errors are 11. |
||
sitl |
✓ | ✓ | ✓ | Adapter and asset-load errors are 11. |
||
bump |
✓ | ✓ | Developer-only release tool. 11 on drift or a missing version part. |
|||
schema-versions |
✓ | Read-only contract discovery (alias contracts). Loads no input; always 0. |
Divergences to branch on carefully¶
These are the cases where a caller that assumes estimate's convention will
misread a result:
sampleandpropagatealways exit0once a run completes. An infeasible Monte Carlo or stochastic outcome is reported in the envelope body, never via10. Read the body's feasibility field; do not rely on the exit code for a NO-GO.scenariohas no12. Every non-PASSEDoutcome — including an unsupported scenario — collapses to10. The same unsupported condition underestimateexits12. Givingscenarioa12is a deliberate future contract change, not a bug.estimatereturns11for a computedFailureKind.INVALID_INPUTeven when the input files are valid. So11fromestimatemeans "invalid input or an input-class feasibility failure"; inspect the body to tell them apart.
Notes for programmatic callers¶
- Pass absolute
--outputpaths. Relative paths resolve against the worker's current directory, which is rarely what you intend. - Do not register the
bumpcommand in a service surface. It is a developer-only release tool that editspyproject.tomlandCHANGELOG.md. - Do not set
BVLOS_SIM_TOOL_VERSIONin the worker environment. It overrides the version embedded in every envelope and is meant only for the test suite (it pins fixtures to a placeholder). In production the version must reflect the installed package. - Treat any code outside
{0, 10, 11, 12, 13}as a harness fault. Shell status1(an uncaught traceback) and2(argument-parser error) are not part of this contract; if you see1, file it as a bug. --progress-format jsonl/--progress-fileadd no exit codes. Onsample,propagate, andbatch, machine-readable progress is a stderr/sidecar side-channel only (one JSON record per interval); it never touches the--outputstream and does not change the exit-code semantics above.