{"count":43,"error_codes":[{"category":"business","code":"ACCOUNT_LOCKED","http_status":403,"message":"The account is temporarily locked after repeated failed sign-in attempts.","remedy":"Wait for the lockout to elapse, or reset the password to clear it immediately.","retryable":false},{"category":"data","code":"CHECKPOINT_UNREADABLE","http_status":500,"message":"A checkpoint exists but could not be decoded into a resumable state.","remedy":"Resume from the previous checkpoint, or restart the task from its last verified milestone.","retryable":false},{"category":"system","code":"CONFIG_INVALID","http_status":500,"message":"Configuration is missing a required value or holds an unusable one.","remedy":"Correct the named environment variable. See .env.example for the expected shape.","retryable":false},{"category":"business","code":"CONFLICT","http_status":409,"message":"The request conflicts with the current state of the resource.","remedy":"Re-read the resource, reconcile against its current state, and retry.","retryable":false},{"category":"external","code":"CONNECTOR_UNAVAILABLE","http_status":501,"message":"A capability is declared but has no working backend in this deployment.","remedy":"Perform this step with the domain's own tool and record the result. Never accept an estimate in place of a run: a value produced without the solver is not an analysis.","retryable":false},{"category":"system","code":"DATABASE_UNAVAILABLE","http_status":503,"message":"The database could not be reached or refused the connection.","remedy":"Verify the database is running and FORGE_DATABASE_URL is correct, then retry.","retryable":true},{"category":"business","code":"DECISION_SUPERSEDED","http_status":409,"message":"This decision has already been superseded, so it is no longer the current answer.","remedy":"Supersede the decision that replaced it instead. Follow the supersession chain to its end to find which one that is.","retryable":false},{"category":"business","code":"EMAIL_ALREADY_REGISTERED","http_status":409,"message":"An account already exists for this email address.","remedy":"Sign in instead, or use the password-reset flow if you have forgotten the password.","retryable":false},{"category":"business","code":"EMAIL_INVALID","http_status":400,"message":"The supplied string is not a syntactically valid email address.","remedy":"Provide an address of the form name@example.com.","retryable":false},{"category":"business","code":"EMAIL_NOT_VERIFIED","http_status":403,"message":"This account exists but its email address has not been verified yet.","remedy":"Open the verification link sent to your inbox, or request a new verification email.","retryable":false},{"category":"business","code":"EVIDENCE_NOT_PRESERVED","http_status":409,"message":"A destructive incident action was attempted before any evidence was preserved.","remedy":"Record a preserve_evidence action first, or run this one as a dry run. Stopping, revoking and rolling back all destroy state an investigation needs, and evidence gathered afterwards is evidence of the response rather than of the incident.","retryable":false},{"category":"external","code":"EXTERNAL_PROTOCOL_ERROR","http_status":502,"message":"An external service replied in a shape this build cannot use.","remedy":"Do not retry: the request or the response contract is wrong. Check the model id and the endpoint, and compare against the provider's current API documentation.","retryable":false},{"category":"external","code":"EXTERNAL_UNAVAILABLE","http_status":503,"message":"An external service could not be reached or returned a server error.","remedy":"Retry; the fault is upstream and usually transient. If it persists, check the provider's status page and FORGE_LLM_BASE_URL.","retryable":true},{"category":"business","code":"FORBIDDEN","http_status":403,"message":"The authenticated principal is not permitted to perform this action on this resource.","remedy":"Request access from the resource owner, or act on a resource within your scope.","retryable":false},{"category":"business","code":"INCIDENT_NOT_REVIEWED","http_status":409,"message":"An incident cannot be closed without a review.","remedy":"Write what happened, what was done, and what would prevent it. SAF-07 names review as one of the seven steps, and a closure without one loses the only part anybody reads later.","retryable":false},{"category":"system","code":"INTERNAL","http_status":500,"message":"An unhandled internal failure occurred.","remedy":"Retry once. If it persists, quote the request_id from this response when reporting it.","retryable":true},{"category":"business","code":"INVALID_CREDENTIALS","http_status":401,"message":"The email address or password did not match an active account.","remedy":"Check the email and password, then try again. Use password reset if needed.","retryable":false},{"category":"data","code":"INVARIANT_VIOLATED","http_status":500,"message":"An operation would have broken a domain invariant and was refused.","remedy":"Report this with the surrounding request_id: it indicates a logic defect, not a user error.","retryable":false},{"category":"business","code":"LAST_OWNER","http_status":409,"message":"This change would leave the project with no owner.","remedy":"Make somebody else an owner first. A project with no owner cannot be administered at all — not even to undo the change that emptied it.","retryable":false},{"category":"external","code":"MAIL_DELIVERY_FAILED","http_status":502,"message":"The mail transport rejected or failed to accept the message.","remedy":"Check SMTP credentials and connectivity. In development, the file transport writes to the mail outbox directory instead.","retryable":true},{"category":"business","code":"MEDIA_DISABLED","http_status":409,"message":"This deployment has no audio media plane configured.","remedy":"Set FORGE_MEDIA_ENABLED=true and restart. Rooms, presence and the live transcript work without it; only shared audio needs it.","retryable":false},{"category":"business","code":"MEMORY_FORGOTTEN","http_status":409,"message":"A user asked FORGE to forget this key, and it is refusing to learn it again.","remedy":"If this should be remembered once more, purge the forgotten entry first — that is a deliberate act, and it is recorded. Otherwise write it under a different key.","retryable":false},{"category":"business","code":"MFA_INVALID","http_status":401,"message":"The second factor was not accepted: wrong code, an already-used one, or a challenge that has expired.","remedy":"Check your device's clock and try the current code. Each code works once; if the authenticator is gone, use a recovery code.","retryable":false},{"category":"business","code":"MFA_REQUIRED","http_status":401,"message":"The password was correct and this account requires a second factor.","remedy":"Submit the six-digit code from your authenticator, or a recovery code, against the challenge id in this response.","retryable":false},{"category":"system","code":"MIGRATION_FAILED","http_status":500,"message":"A schema migration did not apply cleanly.","remedy":"Inspect the named migration and the server log. Do not start the service against a partially migrated schema.","retryable":false},{"category":"business","code":"NOT_AUTHENTICATED","http_status":401,"message":"The request carried no usable session credential.","remedy":"Sign in and retry with the session cookie or bearer token attached.","retryable":false},{"category":"business","code":"NOT_FOUND","http_status":404,"message":"No resource with that identifier is visible to this principal.","remedy":"Check the identifier. A resource you cannot see is reported the same as one that does not exist.","retryable":false},{"category":"business","code":"PASSWORD_TOO_WEAK","http_status":400,"message":"The supplied password did not meet the minimum strength policy.","remedy":"Use at least 12 characters. Longer passphrases are accepted and preferred over symbol substitution.","retryable":false},{"category":"business","code":"PAYLOAD_TOO_LARGE","http_status":413,"message":"The request body exceeded the configured maximum size.","remedy":"Split the payload, or upload large artifacts through the artifact endpoint instead of inline.","retryable":false},{"category":"business","code":"RATE_LIMITED","http_status":429,"message":"Too many attempts from this identity or address within the limiter window.","remedy":"Wait for the interval named in the Retry-After header, then retry.","retryable":true},{"category":"business","code":"ROOM_AT_CAPACITY","http_status":409,"message":"This room already holds as many participants as it supports.","remedy":"Wait for somebody to leave, or raise FORGE_MEDIA_MAX_PARTICIPANTS. PRD NFR-04 sizes a room at 1-20 identified participants; admitting more would degrade the audio for everybody already in it.","retryable":false},{"category":"business","code":"SECRET_NOT_GRANTED","http_status":403,"message":"A tool asked for a secret it has not been granted.","remedy":"Grant the tool that secret if it should have it, or stop the model reaching for it. Grants are per tool on purpose: a permission broad enough to cover a class of tools is broad enough to cover the wrong member of it.","retryable":false},{"category":"business","code":"SECRET_UNAVAILABLE","http_status":424,"message":"A referenced secret is unknown, revoked, or its environment variable is not set in this process.","remedy":"Check the handle name against `forgectl secrets list`. FORGE brokers secrets rather than storing them, so the value must be exported where the service starts.","retryable":false},{"category":"system","code":"SERIALIZATION_FAILED","http_status":500,"message":"A value could not be encoded to or decoded from its stored representation.","remedy":"This indicates a schema/code mismatch. Check that the binary matches the migrated schema version.","retryable":false},{"category":"business","code":"SESSION_EXPIRED","http_status":401,"message":"The session has passed its absolute or idle expiry.","remedy":"Sign in again to obtain a fresh session.","retryable":false},{"category":"business","code":"SESSION_REVOKED","http_status":401,"message":"The session was explicitly revoked (sign-out, password change, or administrative action).","remedy":"Sign in again. If you did not expect this, review recent account activity.","retryable":false},{"category":"data","code":"STATE_CORRUPT","http_status":500,"message":"A persisted record failed its structural invariants when read back.","remedy":"Quarantine the named record and inspect it. Do not let the agent resume against corrupt state.","retryable":false},{"category":"business","code":"TOKEN_ALREADY_USED","http_status":400,"message":"This token has already been redeemed once.","remedy":"If the action did not take effect, request a new link and retry.","retryable":false},{"category":"business","code":"TOKEN_EXPIRED","http_status":400,"message":"The token was issued but its validity window has passed.","remedy":"Request a new link; the previous one is no longer accepted.","retryable":false},{"category":"business","code":"TOKEN_INVALID","http_status":400,"message":"The token does not correspond to any issued token.","remedy":"Request a new link. Tokens are single-use and cannot be reconstructed by hand.","retryable":false},{"category":"business","code":"TOOL_REFUSED","http_status":403,"message":"The policy plane declined to run this tool for this goal.","remedy":"Raise the goal's autonomy level or grant the missing capability if that is appropriate. A prohibited (R5) action is refused regardless of permissions.","retryable":false},{"category":"business","code":"UNSUPPORTED_MEDIA_TYPE","http_status":415,"message":"The request Content-Type is not supported by this endpoint.","remedy":"Send application/json unless the endpoint documents another type.","retryable":false},{"category":"business","code":"VALIDATION_FAILED","http_status":400,"message":"One or more request fields failed validation.","remedy":"Correct the fields named in the details array and resubmit.","retryable":false}]}
