ax-check rule

AXC-C012: Version output is not plain

--version did not print a version number on its own first line, so a script cannot read it reliably.

ax-check is a checker being prepared for release. This page documents the rule ahead of that release; see all 50 rules.

Severityinfo
KindObserved. Depends on the program and environment at run time.
Modeax-check probe-cli
Applies toCommand-line programs, run as a subprocess
Pattern tagsnon-interactive, drift
Fix in one lineMake --version print just the version, for example "1.4.2", and exit 0.

--version either failed, printed no version number on its first line, or printed more than three lines. A script that wants to know which version it is talking to cannot read it reliably.

What it checks

The version probe runs <cmd> --version. The rule fires when any one of these is true: the exit status is not 0, the first line has no version number of the form digits.digits (for example 1.4), or the output is longer than three non-blank lines. A probe that timed out is skipped, because AXC-C001 reports it. Output on stderr is used when stdout is empty.

Why it matters

Versions are how instructions and tools stay in step. An agent reads a skill or an AGENTS.md file that says “use --status with invoicer 1.4 or later”, then needs to check what is installed. The GNU Coding Standards say every program should support --version and --help. When the output is a banner, a changelog, or a prompt to update, the agent has to guess which line holds the number. This is related to drift: the ax-check drift command compares claims in documents against what the program really reports.

Public issues show this is not only a theoretical concern. cloudflare/cf issue #105 listed --version not being machine-readable among its complaints, and the --version part was later fixed. This is context, not a measure of how common the problem is.

How to fix

Make --version print one short line with the program name and number, or just the number, and exit 0. Put the long banner, licence text and update notices elsewhere.

Example

Before

$ invoicer --version </dev/null; echo $?
  ___ _ ___  ___ ___ ___ ___
 |_ _| | _ \/ _ \_ _/ __| __|
  | || |   / (_) | | (__| _|
 |___|_|_|_\\___/___\___|___|
Build: stable
A new release is available!
Run "invoicer upgrade" to update.
0

After

$ invoicer --version </dev/null; echo $?
invoicer 1.4.2
0

A Node fix:

if (process.argv.includes('--version')) {
  process.stdout.write(`invoicer ${pkg.version}\n`);
  process.exit(0);
}

How ax-check detects it

ax-check looks for the pattern digits, a dot, digits in the first line, so 1.4.2, invoicer 1.4.2 and v2.0 all pass. It counts the non-blank lines and allows up to three, so a short licence line is fine. It does not check that the number is correct. It also does not check pre-release suffixes.

Known false positives: a program that identifies itself by a date or a single integer, for example build 20260901. Silence the rule with --disable AXC-C012 if you use such a scheme on purpose.

To reproduce by hand: invoicer --version </dev/null; echo $?, then count lines with invoicer --version </dev/null | grep -c ..

Safety note: This rule uses the default --version probe. probe-cli executes your program under your own OS account. The temporary working directory and HOME it uses are not a sandbox: the program can still read and write anything your account can, and use the network. Probe a CLI you have not reviewed only inside a container or a throwaway virtual machine. Run ax-check probe-cli --dry-run -- invoicer first to see the probes that would run, and see the “Probe safety” section of the ax-check README for what is and is not isolated.

Sources

Records in the AX evidence register that share a pattern tag with this rule. A shared tag means the record is about the same pattern, not that it tests this rule. Read the evidence class before the number.