Error codes
When something goes wrong, Guv answers with an RFC 9457 application/problem+json body. It always has a stable code, a plain-English detail, a suggested fix and a docs_url pointing at one of these pages. The guv CLI exits with a predictable code too, so scripts and agents can react without parsing text.
| Exit code | Meaning |
|---|---|
0 |
success |
1 |
not signed in |
2 |
the request or file is not valid |
3 |
forbidden or denied by policy |
4 |
approval required |
5 |
quota or spend cap |
10 |
temporary, safe to retry |
Request problems
Section titled “Request problems”| Code | Status | Means | Exit |
|---|---|---|---|
bad_request |
400 | The request could not be read | 2 |
validation_failed |
422 | Some fields are not valid | 2 |
manifest_invalid |
422 | guv.yaml is not valid | 2 |
reference_unresolved |
422 | A reference could not be resolved | 2 |
secret_missing |
422 | A secret this needs has not been set | 2 |
confirmation_required |
422 | This destructive action needs a typed confirmation | 2 |
immutable_field |
422 | This field cannot be changed after creation | 2 |
volume_shrink_not_supported |
422 | Volumes can grow but not shrink | 2 |
unsupported_api_version |
400 | Unknown Guv-Version | 2 |
idempotency_key_required |
400 | Idempotency-Key header is required | 2 |
idempotency_key_reused |
422 | This Idempotency-Key was already used for a different request | 2 |
method_not_allowed |
405 | Method not allowed | 1 |
not_acceptable |
406 | The requested media type is not available | 1 |
payload_too_large |
413 | The request body is too large | 2 |
unsupported_media_type |
415 | Unsupported Content-Type | 2 |
Signing in and permissions
Section titled “Signing in and permissions”| Code | Status | Means | Exit |
|---|---|---|---|
unauthorized |
401 | You are not signed in | 1 |
token_expired |
401 | Your token has expired | 1 |
passkey_verification_failed |
401 | The passkey check did not pass | 1 |
challenge_expired |
400 | The sign-in or approval challenge has expired | 2 |
mfa_required |
403 | This workspace requires a passkey on every member account | 3 |
forbidden |
403 | You do not have permission to do this | 3 |
dev_login_disabled |
404 | Development login is turned off | 1 |
Agents, approvals and policy
Section titled “Agents, approvals and policy”| Code | Status | Means | Exit |
|---|---|---|---|
scope_missing |
403 | This token lacks a required scope | 3 |
approval_required |
403 | A human needs to approve this | 4 |
agent_budget_exceeded |
403 | This would raise spend beyond the agent token’s daily budget | 4 |
policy_denied |
403 | A policy does not allow this | 3 |
deploy_blocked |
422 | The deploy was blocked by a safety check | 3 |
change_freeze |
403 | A change freeze is in effect | 3 |
Spend, plans and limits
Section titled “Spend, plans and limits”| Code | Status | Means | Exit |
|---|---|---|---|
workspace_suspended |
403 | This workspace is suspended | 3 |
spend_cap_reached |
402 | The spend cap has been reached | 5 |
payment_required |
402 | A payment method or plan upgrade is needed | 5 |
quota_exceeded |
403 | A plan limit has been reached | 5 |
Conflicts and state
Section titled “Conflicts and state”| Code | Status | Means | Exit |
|---|---|---|---|
plan_hash_mismatch |
409 | The live state changed since this plan was made | 2 |
idempotency_request_in_progress |
409 | A request with this Idempotency-Key is still running | 10 |
not_found |
404 | Not found | 1 |
conflict |
409 | This conflicts with the current state | 1 |
already_exists |
409 | Something with this name already exists | 2 |
domain_taken |
409 | This hostname is in use by another project | 2 |
domain_verification_failed |
422 | The DNS records are not right yet | 2 |
operation_not_cancellable |
409 | This operation can no longer be cancelled | 1 |
deployment_not_rollbackable |
409 | This deployment cannot be rolled back to | 1 |
precondition_failed |
412 | The resource changed since you read it | 1 |
CLI sign-in (device flow)
Section titled “CLI sign-in (device flow)”| Code | Status | Means | Exit |
|---|---|---|---|
authorization_pending |
400 | Waiting for the user to approve this device | 10 |
slow_down |
400 | Polling too fast | 10 |
access_denied |
400 | The user denied the request | 1 |
expired_token |
400 | The device code has expired | 1 |
Sign-ups, invitations and the waitlist
Section titled “Sign-ups, invitations and the waitlist”| Code | Status | Means | Exit |
|---|---|---|---|
signups_closed |
403 | Sign-ups are closed | 1 |
invite_required |
403 | An invitation is required | 1 |
invite_invalid |
404 | The invitation is not valid | 1 |
invite_expired |
410 | The invitation has expired | 1 |
invite_used |
409 | The invitation has already been used | 1 |
invite_revoked |
410 | The invitation was revoked | 1 |
bot_check_failed |
422 | The bot check failed | 2 |
terms_not_accepted |
422 | Current terms must be accepted | 2 |
link_expired |
410 | This link has expired | 1 |
Platform and transient errors
Section titled “Platform and transient errors”| Code | Status | Means | Exit |
|---|---|---|---|
kill_switch_engaged |
403 | The AI operations kill switch is on; agents are read-only | 3 |
rate_limited |
429 | Too many requests | 10 |
internal_error |
500 | Something went wrong on our side | 10 |
transient |
503 | A dependency is briefly unavailable | 10 |
timeout |
504 | The request took too long | 10 |