LPM CLI

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"
fi

Do 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

StatusMeaning
0Success, including explicit help or version output.
1Most CLI errors, failed checks, and workspace aggregate failures.
2Invalid CLI arguments or a missing command. A child can also return 2.
Child statusA wrapped single command or root install hook failed with this status.
Failed-task countMultiple 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.json

Suggested 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 pathJSON behavior
lpm runTask result envelope. Child logs go to stderr.
Single or workspace test, bench, lint, fmt, and checkTool result envelope with member status. Failed output can appear inside the result.
lpm exec, lpm dlx, and direct source-file executionChild I/O passes through. --json does not add a CLI result envelope.
lpm audit, lpm tidy, and lpm doctorCommand 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_codeMeaning
usageInvalid arguments or missing command.
auth_requiredAuthentication is required.
env_token_rejectedThe token supplied through the environment was rejected.
credential_storageCredentials could not be stored or read securely.
session_expiredThe stored session expired and recovery did not succeed.
unsupported_auth_sourceThis operation does not support the selected authentication source.
credential_import_unavailableThe external credential source is unavailable.
credential_import_rejectedImported credentials were rejected.
otp_requiredThe registry requires a one-time password.
otp_invalidThe one-time password was rejected.
forbiddenThe authenticated operation is not permitted.
not_foundThe requested resource does not exist.
rate_limitedA service rate limit prevents the request.
networkA network request failed.
httpAn HTTP response or status could not be handled.
registryA registry or package operation failed without a more specific category.
package_install_deniedCurrent access or version state prevents installation, including cache reuse.
publication_unavailableA publication is not available for the requested operation.
pool_attribution_unconfirmedPool installation attribution could not be confirmed.
npm_firewall_blockedLPM Firewall blocked the npm package under the effective policy.
npm_firewall_entitlement_requiredThe requested LPM Firewall feature requires an entitlement.
upstream_proxy_entitlement_requiredThe upstream proxy route requires an entitlement.
pinned_artifact_unavailableA committed artifact pin cannot be retrieved.
selected_artifact_unavailableA newly selected artifact cannot be retrieved.
resolution_failedNo permitted dependency graph satisfies the request.
peer_dependencyPeer requirements cannot be satisfied.
typosquat_suspectedA new direct package name triggers the typosquatting check.
invalid_package_nameThe package name is invalid.
invalid_integrityAn integrity string is malformed.
integrity_mismatchPackage bytes do not match the expected hash.
invalid_versionA version is invalid.
invalid_version_rangeA version range is invalid.
engine_mismatchAn applicable runtime or CLI version requirement is not satisfied.
engineRuntime management failed.
scriptA script or lifecycle phase failed.
sandboxThe sandbox for lifecycle scripts can't be set up, as when the Windows lpm-sandbox-helper.exe is missing. The message names the fix.
taskTask configuration, scheduling, or execution failed.
workspaceWorkspace configuration or member discovery failed.
catalog_entry_invalid_recursive_definitionA catalog entry refers to another catalog entry.
env_validationProject environment validation failed.
pluginA managed tool could not be prepared or launched.
certLocal certificate setup failed.
lpm_homeLPM CLI refused to use the LPM home, as where Git could commit what it holds. The message names the fix.
tunnelTunnel setup or operation failed.
tunnel_accessThe tunnel relay refused the account. error.relay_code gives the reason: plan_required, domain_required, billing_inactive or account_not_found.
storePackage store access or validation failed.
project_fileLPM 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_layoutProject installation paths have an invalid or conflicting layout.
ioA filesystem or stream operation failed.
jsonJSON parsing or serialization failed.
provenance_verificationPublication evidence failed verification.
security_floorA security floor or managed policy rejected weaker protection.
security_approval_storeSigned local security state could not be verified.
security_approval_requiredThe requested security change needs explicit authorization.
sudo_not_supportedThe command ran through unsupported sudo elevation.
self_updateSelf-update failed.
self_update_pausedSelf-update is paused for the selected channel.
self_update_rate_limitedThe update service rate-limited the request.

Checks in CI

OperationFailure condition
lpm auditA finding matches --fail-on, or the audit cannot complete.
lpm tidyUnused dependencies or undeclared imports remain.
lpm doctorA check or requested repair fails. Warnings alone exit 0.
lpm fmt --checkThe formatter reports changes are needed or encounters an error.
Workspace tool commandsA 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.

.github/workflows/ci.yml excerpt
- run: lpm ci
- run: lpm audit --fail-on vuln
- run: lpm test
- run: lpm lint
- run: lpm fmt --check
- run: lpm check

Each 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.

See also