Exit codes
Use process status, command results, and structured error codes to handle failures in scripts and CI.
An exit status of 0 means the command succeeded. Any nonzero status means the operation failed or its requested checks did not pass.
if lpm install --json > install.json 2> install.log; then
echo "Dependencies are ready"
else
status=$?
cat install.log >&2
echo "See install.json for the structured result" >&2
exit "$status"
fiDo not infer the cause from the number alone. A child process can return the same status as a CLI usage or registry error.
Status values
| Status | Meaning |
|---|---|
0 | Success, including explicit help or version output. |
1 | Most CLI errors, failed checks, and workspace aggregate failures. |
2 | Invalid CLI arguments or a missing command. A child can also return 2. |
| Child status | A wrapped single command or root install hook failed with this status. |
| Failed-task count | Multiple local tasks failed. The count is capped at 255; skipped tasks do not count. |
Running lpm without a command prints help and exits 2. Running lpm --json without a command emits a JSON usage error and exits 2.
Explicit --help and version requests remain display output, even with --json.
Wrapped commands and signals
lpm exec, lpm dlx, source-file execution, and single-tool commands preserve the child's exit status. This includes lpm test, lpm bench, lpm lint, lpm fmt, and lpm check.
For lpm run, a single requested task without task dependencies preserves its child status, including pre/post hook failures.
Multiple local tasks return their failed-task count, capped at 255. Workspace task runs return 1 on failure.
On Unix, a child terminated by a signal returns 128 + signal number. For example, SIGTERM produces 143.
The child's numeric status is used directly on Windows.
Root install hooks preserve the failed hook's status. Their JSON error also includes phase and exit_code.
Dependency rebuilds report an aggregate result; their status is not an individual hook's status.
JSON failures
CLI-owned failures normally produce an error envelope on stdout:
{
"schema_version": 1,
"success": false,
"error": "authentication required",
"error_code": "auth_required"
}Use error_code for programmatic decisions. The human-readable error text can change.
Some diagnostics use an object in error, with a message and additional context.
Version 1 identifies the shared error envelope. Success and aggregate results have their own command-specific schemas.
Usage errors
Argument errors use error_code: "usage" and exit 2. Their kind identifies the parser error.
Additional fields can include argument, command, value, valid_values, usage, and hint.
lpm --json install --unknown-option > error.jsonSuggested recovery
When a safe recovery command is available, the envelope includes next_steps:
{
"schema_version": 1,
"success": false,
"error": "authentication required",
"error_code": "auth_required",
"next_steps": [
{
"description": "Authenticate with the LPM.dev Registry",
"command": "lpm login"
}
]
}next_steps is optional. Check the suggested action before you run it.
Resolver failures also carry dependency-specific context; see Resolver failures.
Command results and passthrough
A failed operation does not always emit the shared error envelope:
| Command path | JSON behavior |
|---|---|
| lpm run | Task result envelope. Child logs go to stderr. |
Single or workspace test, bench, lint, fmt, and check | Tool result envelope with member status. Failed output can appear inside the result. |
| lpm exec, lpm dlx, and direct source-file execution | Child I/O passes through. --json does not add a CLI result envelope. |
| lpm audit, lpm tidy, and lpm doctor | Command report plus a status that reflects the selected failure conditions. |
Tool results omit successful child logs and truncate included failed streams at 10 MiB each.
An exit_code: null with an error means the member could not start or prepare its tool.
A command can complete its checks but report findings. For example, doctor can return a completed report with success: true and exit 1.
Use the process status and the command's documented result fields together.
Error-code reference
These codes identify CLI-owned errors. Command reports can carry their own additional fields and finding codes.
error_code | Meaning |
|---|---|
usage | Invalid arguments or missing command. |
auth_required | Authentication is required. |
env_token_rejected | The token supplied through the environment was rejected. |
credential_storage | Credentials could not be stored or read securely. |
session_expired | The stored session expired and recovery did not succeed. |
unsupported_auth_source | This operation does not support the selected authentication source. |
credential_import_unavailable | The external credential source is unavailable. |
credential_import_rejected | Imported credentials were rejected. |
otp_required | The registry requires a one-time password. |
otp_invalid | The one-time password was rejected. |
forbidden | The authenticated operation is not permitted. |
not_found | The requested resource does not exist. |
rate_limited | A service rate limit prevents the request. |
network | A network request failed. |
http | An HTTP response or status could not be handled. |
registry | A registry or package operation failed without a more specific category. |
package_install_denied | Current access or version state prevents installation, including cache reuse. |
publication_unavailable | A publication is not available for the requested operation. |
pool_attribution_unconfirmed | Pool installation attribution could not be confirmed. |
npm_firewall_blocked | LPM Firewall blocked the npm package under the effective policy. |
npm_firewall_entitlement_required | The requested LPM Firewall feature requires an entitlement. |
upstream_proxy_entitlement_required | The upstream proxy route requires an entitlement. |
pinned_artifact_unavailable | A committed artifact pin cannot be retrieved. |
selected_artifact_unavailable | A newly selected artifact cannot be retrieved. |
resolution_failed | No permitted dependency graph satisfies the request. |
peer_dependency | Peer requirements cannot be satisfied. |
typosquat_suspected | A new direct package name triggers the typosquatting check. |
invalid_package_name | The package name is invalid. |
invalid_integrity | An integrity string is malformed. |
integrity_mismatch | Package bytes do not match the expected hash. |
invalid_version | A version is invalid. |
invalid_version_range | A version range is invalid. |
engine_mismatch | An applicable runtime or CLI version requirement is not satisfied. |
engine | Runtime management failed. |
script | A script or lifecycle phase failed. |
sandbox | The sandbox for lifecycle scripts can't be set up, as when the Windows lpm-sandbox-helper.exe is missing. The message names the fix. |
task | Task configuration, scheduling, or execution failed. |
workspace | Workspace configuration or member discovery failed. |
catalog_entry_invalid_recursive_definition | A catalog entry refers to another catalog entry. |
env_validation | Project environment validation failed. |
plugin | A managed tool could not be prepared or launched. |
cert | Local certificate setup failed. |
lpm_home | LPM CLI refused to use the LPM home, as where Git could commit what it holds. The message names the fix. |
tunnel | Tunnel setup or operation failed. |
tunnel_access | The tunnel relay refused the account. error.relay_code gives the reason: plan_required, domain_required, billing_inactive or account_not_found. |
store | Package store access or validation failed. |
project_file | LPM CLI refused to touch a project file, such as a secret destination that Git tracks, or ran where no project is. The message names the fix. |
project_layout | Project installation paths have an invalid or conflicting layout. |
io | A filesystem or stream operation failed. |
json | JSON parsing or serialization failed. |
provenance_verification | Publication evidence failed verification. |
security_floor | A security floor or managed policy rejected weaker protection. |
security_approval_store | Signed local security state could not be verified. |
security_approval_required | The requested security change needs explicit authorization. |
sudo_not_supported | The command ran through unsupported sudo elevation. |
self_update | Self-update failed. |
self_update_paused | Self-update is paused for the selected channel. |
self_update_rate_limited | The update service rate-limited the request. |
Checks in CI
| Operation | Failure condition |
|---|---|
| lpm audit | A finding matches --fail-on, or the audit cannot complete. |
| lpm tidy | Unused dependencies or undeclared imports remain. |
| lpm doctor | A check or requested repair fails. Warnings alone exit 0. |
| lpm fmt --check | The formatter reports changes are needed or encounters an error. |
| Workspace tool commands | A selected member fails or cannot prepare its tool. |
An unmatched workspace filter succeeds with zero packages unless --fail-if-no-match is set.
Use it when an empty selection would hide missing CI coverage.
- run: lpm ci
- run: lpm audit --fail-on vuln
- run: lpm test
- run: lpm lint
- run: lpm fmt --check
- run: lpm checkEach step uses its own exit status. If you pipe output through another program, preserve the command's failure status with your shell's pipeline controls.