Heuristic:Protectai Modelscan Exit Code Conventions
| Knowledge Sources | |
|---|---|
| Domains | Infrastructure, Debugging |
| Last Updated | 2026-02-14 12:00 GMT |
Overview
ModelScan CLI uses semantic exit codes (0-4) designed for CI/CD pipeline integration and automated decision-making.
Description
The ModelScan CLI returns specific exit codes that encode the scan outcome. These codes are designed for scripting and CI/CD integration, where different exit codes can trigger different pipeline behaviors (e.g., fail the build on exit code 1, warn on exit code 2). The codes follow a severity ordering: 0 (clean) < 1 (vulnerabilities found) < 2 (errors) < 3 (no supported files) < 4 (usage error).
Usage
Use these exit codes when integrating ModelScan into automated pipelines, CI/CD workflows, or shell scripts. The codes allow you to distinguish between "model is safe" (0), "model has issues" (1), and various failure modes (2-4), enabling appropriate responses at each level.
The Insight (Rule of Thumb)
- Action: Check the exit code of `modelscan` CLI invocations in scripts and CI/CD pipelines.
- Value: Exit codes follow this convention:
- 0 — Scan completed, no vulnerabilities found (safe)
- 1 — Scan completed, vulnerabilities were found (unsafe)
- 2 — Scan encountered errors or exceptions
- 3 — No supported files were passed to scan
- 4 — CLI usage error (bad arguments)
- Trade-off: None. This is purely informational for integration purposes.
Reasoning
The exit code logic is defined in two places within `cli.py`:
Scan result exit codes from `cli.py:145-156`:
# exit code 3 if no supported files were passed
if not modelscan.scanned:
return 3
# exit code 2 if scan encountered errors
elif modelscan.errors:
return 2
# exit code 1 if scan completed successfully and vulnerabilities were found
elif modelscan.issues.all_issues:
return 1
# exit code 0 if scan completed successfully and no vulnerabilities were found
else:
return 0
CLI-level error handling from `cli.py:194-212`:
def main() -> None:
result = 0
try:
result = cli.main(standalone_mode=False)
except click.ClickException as e:
click.echo(f"Error: {e}")
with click.Context(cli) as ctx:
click.echo(cli.get_help(ctx))
# exit code 4 for CLI usage errors
result = 4
except Exception as e:
click.echo(f"Exception: {e}")
# exit code 2 if scan throws exceptions
result = 2
finally:
sys.exit(result)
The priority ordering means errors (2) take precedence over vulnerabilities (1), and no supported files (3) take precedence over errors. This ensures the most severe/actionable condition is always reported.