This document defines how the CLI reports errors in human-readable and structured form.
Errors are part of the product surface. They are not implementation leftovers.
Use cli-style-guide.md for tone and presentation, and output-conventions.md for stream rules.
A good CLI error must:
- say what failed
- identify the relevant boundary when it matters
- say what the user can do next
- fail closed around production
A bad CLI error:
- hides target context
- exposes raw internals instead of user meaning
- stops without a next step
An expected, explainable condition where the command cannot complete as requested.
Examples:
- invalid flags or conflicting arguments
- missing project context
- deploy target not allowed
- blocked protected action
- target CLI capability exists, but the current preview cannot support it yet
Expected failures should:
- have stable structured codes
- include actionable context
- return a structured envelope at the command boundary
An expected external fault, not a product bug.
Examples:
- network timeout
- platform API unavailable
- permission or auth failure
- underlying runtime or build system failure
Operational errors may be translated into stable structured envelopes when that improves recovery, but they should not be disguised as programming bugs.
An unexpected fault or invariant break where the system cannot reliably continue.
Examples:
- impossible branch reached
- unexpected
undefined - internal serialization or state invariant broken
Bugs should fail fast and preserve stack traces. Catch them only at the outermost boundary for crash formatting.
- internals may throw structured failures to abort quickly and preserve context
- command boundaries convert expected failures into the documented error envelope
- operational errors may be translated at boundaries when helpful
- unknown errors should not be broadly wrapped into fake "expected" failures
Human-readable errors should follow this shape:
- first line: short summary plus stable code
- relevant context such as project, branch, app, or deployment
- why
- fix
- where when relevant
- hint for
-vor--tracewhen helpful
Example:
Build failed locally.
✗ Built next build exited with code 1
Fix: Inspect the build output above, fix the error, and redeploy.
If the deployment starts but the app is not ready yet, list the deployment URL and point to runtime logs without claiming a health-check result until the platform exposes one:
The deployment started, but the app is not ready yet.
This is usually a missing env var, a failed DB connection,
or a crash on startup.
See what happened
prisma-cli app logs --deployment <id>
URL
https://cv-...
Commands run with --json should emit this envelope on failure:
{
"ok": false,
"command": "app.deploy",
"error": {
"code": "BUILD_FAILED",
"domain": "app",
"severity": "error",
"summary": "Deployment failed during build",
"why": "Next.js build returned a non-zero exit code",
"fix": "Inspect logs and redeploy after fixing the build",
"where": null,
"meta": {},
"docsUrl": null
},
"warnings": [],
"nextSteps": [],
"nextActions": []
}Rules:
okis alwaysfalsecommandis always presenterror.codeis stable and machine-readableerror.domainis a stable logical area such ascli,agent,auth,project,branch,app, ordatabaseerror.severityis stable and machine-readableerror.summaryis the short human-readable headlineerror.whyexplains the immediate cause when knownerror.fixexplains the next useful recovery step when knownerror.wherepoints to the relevant location when applicableerror.metais structured, not free-form proseerror.docsUrlmay benullwhen no per-code doc exists yetwarnings,nextSteps, andnextActionsare always present- agents and CI should branch on structured error fields, not prose strings
These codes are the minimum stable set for the MVP:
USAGE_ERRORAUTH_REQUIREDAUTH_CONFIG_INVALIDAGENT_SKILLS_INSTALL_FAILEDWORKSPACE_SWITCH_UNAVAILABLEWORKSPACE_NOT_AUTHENTICATEDWORKSPACE_AMBIGUOUSPROJECT_SETUP_REQUIREDPROJECT_LINK_TARGET_REQUIREDPROJECT_CREATE_FAILEDPROJECT_RENAME_FAILEDPROJECT_REMOVE_BLOCKEDPROJECT_TRANSFER_REJECTEDPROJECT_API_ERRORTRANSFER_RECIPIENT_REQUIREDTRANSFER_RECIPIENT_UNAVAILABLEPROJECT_NOT_FOUNDPROJECT_AMBIGUOUSAPP_AMBIGUOUSLOCAL_PROJECT_WORKSPACE_MISMATCHLOCAL_STATE_WRITE_FAILEDLOCAL_STATE_STALEBRANCH_NOT_DEPLOYABLEBRANCH_NOT_FOUNDBRANCH_PROTECTEDBRANCH_NOT_EMPTYBRANCH_CASCADE_INCOMPLETECOMPUTE_CONFIG_INVALIDCOMPUTE_CONFIG_TARGET_REQUIREDCOMPUTE_CONFIG_TARGET_UNKNOWNBUILD_SETTINGS_MIGRATION_REQUIREDBUILD_SETTINGS_UNSUPPORTEDFRAMEWORK_NOT_DETECTEDDEPLOYMENT_NOT_FOUNDNO_DEPLOYMENTSNO_PREVIOUS_DEPLOYMENTPROD_DEPLOY_REQUIRES_FLAGPROMOTE_SOURCE_INVALIDROLLBACK_UNAVAILABLECONFIRMATION_REQUIREDDOMAIN_HOSTNAME_INVALIDDOMAIN_DNS_NOT_CONFIGUREDDOMAIN_ALREADY_REGISTEREDDOMAIN_QUOTA_EXCEEDEDDOMAIN_NOT_FOUNDDOMAIN_RETRY_NOT_ELIGIBLEDOMAIN_VERIFICATION_FAILEDDOMAIN_VERIFICATION_TIMEOUTREMOVE_FAILEDFEATURE_UNAVAILABLEREPO_PROVIDER_UNSUPPORTEDREPO_INSTALLATION_REQUIREDREPO_NOT_ACCESSIBLEREPO_NOT_CONNECTEDREPO_ALREADY_CONNECTEDREPO_CONNECTION_FAILEDBUILD_FAILEDBRANCH_DATABASE_SETUP_FAILEDSCHEMA_SETUP_FAILEDDATABASE_NOT_FOUNDDATABASE_AMBIGUOUSDATABASE_CONNECTION_NOT_FOUNDDATABASE_CONNECTION_MISSINGDATABASE_CONNECTION_STRING_MISSINGDATABASE_API_ERRORDATABASE_BACKUPS_UNSUPPORTEDDATABASE_BACKUP_NOT_FOUNDDATABASE_RESTORE_CONFLICTRUN_FAILEDDEPLOY_FAILEDVERSION_UNAVAILABLECOMMAND_CANCELED
Recommended meanings:
USAGE_ERROR: invalid arguments or invalid command combinationAUTH_REQUIRED: command needs an authenticated sessionAUTH_CONFIG_INVALID: environment auth configuration is present but unusable, such as an emptyPRISMA_SERVICE_TOKENAGENT_SKILLS_INSTALL_FAILED: installing Prisma skills through the external skills CLI failed; callers should inspect the command, exit code, and stderr inerror.metaWORKSPACE_SWITCH_UNAVAILABLE:PRISMA_SERVICE_TOKENis the active auth source, so local OAuth workspace switching cannot applyWORKSPACE_NOT_AUTHENTICATED: requested workspace is not present in the local OAuth credentials store for a switch/logout operation; callers should runauth loginfor that workspaceWORKSPACE_AMBIGUOUS: requested workspace name matches more than one local OAuth workspace; callers should switch by workspace idPROJECT_SETUP_REQUIRED: command needs explicit or durable Project context before it can continuePROJECT_LINK_TARGET_REQUIRED:project linkneeds the user to choose an existing Project or create a new onePROJECT_CREATE_FAILED: Project creation failed before deployment or linking could continuePROJECT_RENAME_FAILED: the platform rejected the new project namePROJECT_REMOVE_BLOCKED: project removal is blocked while it still has active deploymentsPROJECT_TRANSFER_REJECTED: the platform rejected the transfer, for example an invalid or expired recipient tokenPROJECT_API_ERROR: project Management API request failed without a more specific CLI error codeTRANSFER_RECIPIENT_REQUIRED: project transfer needs --to-workspace or --recipient-tokenTRANSFER_RECIPIENT_UNAVAILABLE: --to-workspace cannot resolve local OAuth sessions while PRISMA_SERVICE_TOKEN is setPROJECT_NOT_FOUND: requested project does not exist or is not accessiblePROJECT_AMBIGUOUS: multiple safe project candidates matchedAPP_AMBIGUOUS: multiple apps matched the inferred or explicit app targetLOCAL_PROJECT_WORKSPACE_MISMATCH: local Project pin points at a different workspace than the active authenticated workspace; callers should switch to the linked workspace or relink the directoryLOCAL_STATE_WRITE_FAILED: the CLI could not save local Project binding state such as.prisma/local.jsonor the matching.gitignoreentry; callers should fix directory permissions or filesystem state before retryingLOCAL_STATE_STALE: local Project pin no longer matches platform data and continuing would be ambiguousBRANCH_NOT_DEPLOYABLE: command tried to deploy to a non-deployable branch contextBRANCH_NOT_FOUND: requested branch id or git name does not exist in the resolved projectBRANCH_PROTECTED: branch removal refused because the branch is the project's production or default branchBRANCH_NOT_EMPTY: branch removal refused because the branch still has live apps or databasesBRANCH_CASCADE_INCOMPLETE: a --cascade branch removal failed partway; meta lists the resources already removed and the branch remainsCOMPUTE_CONFIG_INVALID:prisma.compute.tsfailed to load or validateCOMPUTE_CONFIG_TARGET_REQUIRED: a multi-app compute config needs an[app]target and none was given or inferredCOMPUTE_CONFIG_TARGET_UNKNOWN: the[app]target matches no configured appBUILD_SETTINGS_MIGRATION_REQUIRED: a legacyprisma.app.jsoncontains custom build settings that must move into thebuildblock ofprisma.compute.tsBUILD_SETTINGS_UNSUPPORTED: a compute configbuildblock targets a framework whose SDK strategy does not consume committed build settingsFRAMEWORK_NOT_DETECTED: app deploy could not detect a supported Beta framework and no explicit framework/build type was providedDEPLOYMENT_NOT_FOUND: requested deployment id does not existNO_DEPLOYMENTS: command resolved a branch or app but found no deploymentsNO_PREVIOUS_DEPLOYMENT: rollback could not find an earlier deployment for the selected appPROD_DEPLOY_REQUIRES_FLAG: app deploy resolved a production Branch with a prior production deployment, but--prodwas not passedPROMOTE_SOURCE_INVALID: source for promote is missing, invalid, or not promotableROLLBACK_UNAVAILABLE: no previous healthy production deployment existsCONFIRMATION_REQUIRED: command cannot continue without confirmation in the current modeDOMAIN_HOSTNAME_INVALID: custom-domain hostname is malformed or rejected by the platformDOMAIN_DNS_NOT_CONFIGURED: custom-domain hostname does not yet point to the required Prisma DNS targetDOMAIN_ALREADY_REGISTERED: custom-domain hostname is already attached outside the selected appDOMAIN_QUOTA_EXCEEDED: selected app has reached its custom-domain quotaDOMAIN_NOT_FOUND: requested custom domain is not attached to the selected appDOMAIN_RETRY_NOT_ELIGIBLE: requested custom domain is not in a state where verification can be retriedDOMAIN_VERIFICATION_FAILED: custom-domain verification reached a terminal failed stateDOMAIN_VERIFICATION_TIMEOUT: custom-domain verification did not reach a terminal state before the requested timeoutREMOVE_FAILED: app removal could not complete remotelyFEATURE_UNAVAILABLE: the command exists in the CLI model, but the current preview cannot support it yetREPO_PROVIDER_UNSUPPORTED: repository connection received a non-GitHub repository URLREPO_INSTALLATION_REQUIRED: repository connection needs a GitHub App installation before the project can be linkedREPO_NOT_ACCESSIBLE: the connected GitHub App installations do not expose the requested repositoryREPO_NOT_CONNECTED: a command expected a project repository connection, but none existsREPO_ALREADY_CONNECTED: a project already has a different GitHub repository connectedREPO_CONNECTION_FAILED: the Management API repository connection operation failedBUILD_FAILED: build failed before a healthy deployment existedBRANCH_DATABASE_SETUP_FAILED: database creation or env-var wiring failed before deployment startedSCHEMA_SETUP_FAILED: local Prisma schema source setup against a newly created database failed before deployment startedDATABASE_NOT_FOUND: requested database id or name does not exist in the resolved project scopeDATABASE_AMBIGUOUS: requested database name matches multiple databases and needs an id or branch filterDATABASE_CONNECTION_NOT_FOUND: requested database connection id does not exist or is not accessibleDATABASE_CONNECTION_MISSING: database creation succeeded but the API response did not include the first one-time connection payloadDATABASE_CONNECTION_STRING_MISSING: connection creation succeeded but the API response did not include the one-time connection stringDATABASE_API_ERROR: database Management API request failed without a more specific CLI error codeDATABASE_BACKUPS_UNSUPPORTED: the platform does not manage backups for the database, for example remote/BYO databasesDATABASE_BACKUP_NOT_FOUND: requested backup id does not exist for the resolved source databaseDATABASE_RESTORE_CONFLICT: restore target database is provisioning or already recoveringRUN_FAILED: local framework run command could not be started or exited unsuccessfullyDEPLOY_FAILED: deployment or post-build health failedVERSION_UNAVAILABLE: CLI could not read its own bundled package metadata to report a version (defensive; not expected in normal installs)COMMAND_CANCELED: command execution was canceled by a runtime cancellation signal such asSIGINTorSIGTERM
The MVP should use these process exit codes:
0: success1: runtime or command failure2: usage or configuration error130: command cancellation
Stable structured error codes, not exit code granularity, are the main branching surface for agents and CI.
Cancellation intentionally uses 130 instead of the generic runtime failure code because it has established shell semantics for interrupted commands and is useful to operators and process supervisors. Agents and CI should still branch on COMMAND_CANCELED rather than the numeric exit code.
Production-related failures should fail closed.
That means:
- do not guess production intent
- do not proceed when target resolution is unclear
- do not hide whether production changed
If a production action is blocked or fails, the output should make clear whether production stayed unchanged.
Every error should help the user recover without opening another document first.
If a condition is expected and actionable, document it as a structured failure. If it is a bug, do not hide it behind a fake user-facing success envelope.