http/error_schemas.ts

Standard error response schemas and error code constants for fuz_app routes.

Defines ERROR_* constants (single source of truth for machine-parseable error codes), Zod schemas for error response shapes, a type for error schema maps, and derive_error_schemas to auto-populate middleware-produced errors from a route's auth requirement and input schema.

Used in RouteSpec.errors and MiddlewareSpec.errors for surface introspection and DEV-mode validation.

view source

Declarations
#

55 declarations

AccountVanishedError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "account_vanished"; } import {AccountVanishedError} from '@fuzdev/fuz_app/http/error_schemas.js';

error

type "account_vanished"

[key: string]

type unknown

ActorNotOnAccountError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "actor_not_on_account"; } import {ActorNotOnAccountError} from '@fuzdev/fuz_app/http/error_schemas.js';

error

type "actor_not_on_account"

[key: string]

type unknown

ActorRequiredError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "actor_required"; available: { [x: string]: unknown; id: string; name: string; }[]; } import {ActorRequiredError} from '@fuzdev/fuz_app/http/error_schemas.js';

Authorization-phase failure shapes. Surfaced when the dispatcher's apply_authorization_phase rejects a request before the handler runs — the route is acting-aware (input declares acting?: ActingActor or auth requires role_grants), but actor resolution failed.

400: actor_required (with available[]) for unspecified-actor on a multi-actor account; actor_not_on_account for a supplied actor id that doesn't belong to the authenticated account.

500: no_actors_on_account for a signup-invariant violation (the actor list enumerated empty); account_vanished for a torn-read race (account/actor row deleted between credential validation and the dispatcher's follow-up read).

Used by derive_error_schemas when auth.actor !== 'none' so the merged error surface matches what the dispatcher actually emits.

error

type "actor_required"

available

type { [x: string]: unknown; id: string; name: string; }[]

[key: string]

type unknown

ApiError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: string; } import {ApiError} from '@fuzdev/fuz_app/http/error_schemas.js';

Base API error — all JSON error responses have at least {error: string}.

error

type string

[key: string]

type unknown

CredentialTypeRequiredError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "credential_type_required"; required_credential_types: readonly string[]; } import {CredentialTypeRequiredError} from '@fuzdev/fuz_app/http/error_schemas.js';

Credential-type error — returned by the dispatcher's post-authorization credential gate (and the require_credential_types REST middleware) when the request's credential type isn't in the route's auth.credential_types allowlist.

required_credential_types carries what the route declared (['daemon_token'] for keeper; future gates carry their own labels). Symmetric with PermissionError's required_roles: clients see what the route demanded, not what their credential is.

error

type "credential_type_required"

required_credential_types

type readonly string[]

[key: string]

type unknown

derive_error_schemas
#

http/error_schemas.ts view source

({ auth, has_input, has_params, has_query, rate_limit, checks_content_type }: DeriveErrorSchemasOptions): Partial<Record<number, ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>>>> import {derive_error_schemas} from '@fuzdev/fuz_app/http/error_schemas.js';

__0

returns

Partial<Record<number, ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>>>>

DeriveErrorSchemasOptions
#

http/error_schemas.ts view source

DeriveErrorSchemasOptions import type {DeriveErrorSchemasOptions} from '@fuzdev/fuz_app/http/error_schemas.js';

Derive error schemas from a route's auth requirement, input schema, and rate limit config.

Returns the error schemas that middleware will auto-produce for this route. Route handlers can declare additional error schemas via RouteSpec.errors; explicit entries override auto-derived ones for the same status code.

Derivation rules under the new flat-record auth shape:

auth

type RouteAuth

has_input?

type boolean

has_params?

type boolean

has_query?

type boolean

rate_limit?

type RateLimitKey

checks_content_type?

type boolean

ERROR_ACCOUNT_NOT_FOUND
#

http/error_schemas.ts view source

"account_not_found" import {ERROR_ACCOUNT_NOT_FOUND} from '@fuzdev/fuz_app/http/error_schemas.js';

Token references a deleted account.

ERROR_ACCOUNT_VANISHED
#

http/error_schemas.ts view source

"account_vanished" import {ERROR_ACCOUNT_VANISHED} from '@fuzdev/fuz_app/http/error_schemas.js';

Authentication validated an account, but a follow-up read in the authorization phase came back null — the account or its named actor row was deleted between the credential check and the dispatcher's build_request_context / build_account_context step. Torn read, not a missing-actor invariant violation. Surfaced as 500 so the operator sees the race signal; clients can retry. Distinct from ERROR_ACCOUNT_NOT_FOUND (stale token referencing a long-deleted account, raised at credential validation) and ERROR_NO_ACTORS_ON_ACCOUNT (the actor list enumerated empty).

ERROR_ACTOR_NOT_ON_ACCOUNT
#

http/error_schemas.ts view source

"actor_not_on_account" import {ERROR_ACTOR_NOT_ON_ACCOUNT} from '@fuzdev/fuz_app/http/error_schemas.js';

Supplied acting field does not name an actor on the authenticated account.

ERROR_ACTOR_REQUIRED
#

http/error_schemas.ts view source

"actor_required" import {ERROR_ACTOR_REQUIRED} from '@fuzdev/fuz_app/http/error_schemas.js';

Multi-actor account requires the request to carry an explicit acting field naming the actor the request is acting as, so the dispatcher's authorization phase doesn't pick a default actor silently. Returned with the available actors so the client can prompt.

ERROR_ALREADY_BOOTSTRAPPED
#

http/error_schemas.ts view source

"already_bootstrapped" import {ERROR_ALREADY_BOOTSTRAPPED} from '@fuzdev/fuz_app/http/error_schemas.js';

Bootstrap lock already acquired — system already bootstrapped.

ERROR_AUTHENTICATION_REQUIRED
#

http/error_schemas.ts view source

"authentication_required" import {ERROR_AUTHENTICATION_REQUIRED} from '@fuzdev/fuz_app/http/error_schemas.js';

No valid session or bearer token.

ERROR_CREDENTIAL_TYPE_REQUIRED
#

http/error_schemas.ts view source

"credential_type_required" import {ERROR_CREDENTIAL_TYPE_REQUIRED} from '@fuzdev/fuz_app/http/error_schemas.js';

Route requires a credential type the request didn't arrive on. Symmetric with ERROR_INSUFFICIENT_PERMISSIONS + required_roles: the body carries required_credential_types: ReadonlyArray<string> — what the route demanded, not what arrived. Today the only credential gate is keeper (['daemon_token']); future gates (agent_token, group_actor_token) reuse the same literal and label themselves through the array.

ERROR_DATABASE_CONNECTION_FAILED
#

http/error_schemas.ts view source

"database_connection_failed" import {ERROR_DATABASE_CONNECTION_FAILED} from '@fuzdev/fuz_app/http/error_schemas.js';

Database health-check query failed (connectivity or query error).

ERROR_FORBIDDEN_ORIGIN
#

http/error_schemas.ts view source

"forbidden_origin" import {ERROR_FORBIDDEN_ORIGIN} from '@fuzdev/fuz_app/http/error_schemas.js';

Request origin not in allowlist.

ERROR_FOREIGN_KEY_VIOLATION
#

http/error_schemas.ts view source

"foreign_key_violation" import {ERROR_FOREIGN_KEY_VIOLATION} from '@fuzdev/fuz_app/http/error_schemas.js';

DELETE blocked by a foreign key constraint.

ERROR_INSUFFICIENT_PERMISSIONS
#

http/error_schemas.ts view source

"insufficient_permissions" import {ERROR_INSUFFICIENT_PERMISSIONS} from '@fuzdev/fuz_app/http/error_schemas.js';

Authenticated but missing required role.

ERROR_INVALID_CONTENT_LENGTH
#

http/error_schemas.ts view source

"invalid_content_length" import {ERROR_INVALID_CONTENT_LENGTH} from '@fuzdev/fuz_app/http/error_schemas.js';

Request Content-Length header is not a plain run of ASCII digits.

ERROR_INVALID_CREDENTIALS
#

http/error_schemas.ts view source

"invalid_credentials" import {ERROR_INVALID_CREDENTIALS} from '@fuzdev/fuz_app/http/error_schemas.js';

Username or password is wrong (intentionally vague for enumeration prevention).

ERROR_INVALID_EVENT_TYPE
#

http/error_schemas.ts view source

"invalid_event_type" import {ERROR_INVALID_EVENT_TYPE} from '@fuzdev/fuz_app/http/error_schemas.js';

Query parameter event_type is not a valid audit event type.

ERROR_INVALID_JSON_BODY
#

http/error_schemas.ts view source

"invalid_json_body" import {ERROR_INVALID_JSON_BODY} from '@fuzdev/fuz_app/http/error_schemas.js';

Request body is not valid JSON or not an object.

ERROR_INVALID_QUERY_PARAMS
#

http/error_schemas.ts view source

"invalid_query_params" import {ERROR_INVALID_QUERY_PARAMS} from '@fuzdev/fuz_app/http/error_schemas.js';

URL query params failed Zod validation.

ERROR_INVALID_REQUEST_BODY
#

http/error_schemas.ts view source

"invalid_request_body" import {ERROR_INVALID_REQUEST_BODY} from '@fuzdev/fuz_app/http/error_schemas.js';

Request body failed Zod validation.

ERROR_INVALID_ROUTE_PARAMS
#

http/error_schemas.ts view source

"invalid_route_params" import {ERROR_INVALID_ROUTE_PARAMS} from '@fuzdev/fuz_app/http/error_schemas.js';

URL path params failed Zod validation.

ERROR_INVALID_TOKEN
#

http/error_schemas.ts view source

"invalid_token" import {ERROR_INVALID_TOKEN} from '@fuzdev/fuz_app/http/error_schemas.js';

Bearer token failed validation (missing, malformed, or revoked).

ERROR_INVITE_ACCOUNT_EXISTS_EMAIL
#

http/error_schemas.ts view source

"invite_account_exists_email" import {ERROR_INVITE_ACCOUNT_EXISTS_EMAIL} from '@fuzdev/fuz_app/http/error_schemas.js';

An account already exists with this invite's email.

ERROR_INVITE_ACCOUNT_EXISTS_USERNAME
#

http/error_schemas.ts view source

"invite_account_exists_username" import {ERROR_INVITE_ACCOUNT_EXISTS_USERNAME} from '@fuzdev/fuz_app/http/error_schemas.js';

An account already exists with this invite's username.

ERROR_INVITE_DUPLICATE
#

http/error_schemas.ts view source

"invite_duplicate" import {ERROR_INVITE_DUPLICATE} from '@fuzdev/fuz_app/http/error_schemas.js';

An unclaimed invite already exists for this email or username.

ERROR_INVITE_NOT_FOUND
#

http/error_schemas.ts view source

"invite_not_found" import {ERROR_INVITE_NOT_FOUND} from '@fuzdev/fuz_app/http/error_schemas.js';

Invite not found (for delete operations).

ERROR_KEEPER_ACCOUNT_NOT_FOUND
#

http/error_schemas.ts view source

"keeper_account_not_found" import {ERROR_KEEPER_ACCOUNT_NOT_FOUND} from '@fuzdev/fuz_app/http/error_schemas.js';

Keeper account ID set but account row not found.

ERROR_NO_ACTORS_ON_ACCOUNT
#

http/error_schemas.ts view source

"no_actors_on_account" import {ERROR_NO_ACTORS_ON_ACCOUNT} from '@fuzdev/fuz_app/http/error_schemas.js';

Authenticated account exists but has no actors. Server invariant violation — signup / bootstrap always create an actor in the same transaction. Surfaced from the dispatcher's authorization phase as a 500 so the operator sees the corruption signal rather than a confusing 4xx. Distinct from ERROR_ACCOUNT_VANISHED: the actor list was enumerated successfully and came back empty.

ERROR_NO_MATCHING_INVITE
#

http/error_schemas.ts view source

"no_matching_invite" import {ERROR_NO_MATCHING_INVITE} from '@fuzdev/fuz_app/http/error_schemas.js';

No unclaimed invite matches the signup credentials.

ERROR_PAYLOAD_TOO_LARGE
#

http/error_schemas.ts view source

"payload_too_large" import {ERROR_PAYLOAD_TOO_LARGE} from '@fuzdev/fuz_app/http/error_schemas.js';

Request body exceeds the maximum allowed size.

ERROR_RATE_LIMIT_EXCEEDED
#

http/error_schemas.ts view source

"rate_limit_exceeded" import {ERROR_RATE_LIMIT_EXCEEDED} from '@fuzdev/fuz_app/http/error_schemas.js';

Rate limiter rejected the request.

ERROR_ROLE_GRANT_NOT_FOUND
#

http/error_schemas.ts view source

"role_grant_not_found" import {ERROR_ROLE_GRANT_NOT_FOUND} from '@fuzdev/fuz_app/http/error_schemas.js';

Role grant ID not found or not owned by the target actor.

ERROR_ROLE_NOT_WEB_GRANTABLE
#

http/error_schemas.ts view source

"role_not_web_grantable" import {ERROR_ROLE_NOT_WEB_GRANTABLE} from '@fuzdev/fuz_app/http/error_schemas.js';

Admin tried to grant a role that is not web-grantable.

ERROR_ROW_NOT_FOUND
#

http/error_schemas.ts view source

"row_not_found" import {ERROR_ROW_NOT_FOUND} from '@fuzdev/fuz_app/http/error_schemas.js';

Row with the given PK value not found.

ERROR_SIGNUP_CONFLICT
#

http/error_schemas.ts view source

"signup_conflict" import {ERROR_SIGNUP_CONFLICT} from '@fuzdev/fuz_app/http/error_schemas.js';

Signup conflict — username or email already taken (intentionally vague for enumeration prevention).

ERROR_TABLE_NO_PRIMARY_KEY
#

http/error_schemas.ts view source

"table_no_primary_key" import {ERROR_TABLE_NO_PRIMARY_KEY} from '@fuzdev/fuz_app/http/error_schemas.js';

Table has no single-column primary key, so there is no column the row-DELETE can target: either no primary key at all, or a composite one (a single-column WHERE on one member of a composite key over-matches).

ERROR_TABLE_NOT_DELETABLE
#

http/error_schemas.ts view source

"table_not_deletable" import {ERROR_TABLE_NOT_DELETABLE} from '@fuzdev/fuz_app/http/error_schemas.js';

Table is excluded from row deletion by policy — the audit trail and the framework's singleton bookkeeping rows (bootstrap_lock, app_settings, schema_version), whose invariants live in the domain layer rather than in a generic storage endpoint. See http/db_routes.ts's NON_DELETABLE_TABLES.

ERROR_TABLE_NOT_FOUND
#

http/error_schemas.ts view source

"table_not_found" import {ERROR_TABLE_NOT_FOUND} from '@fuzdev/fuz_app/http/error_schemas.js';

Table name not found in information_schema.

ERROR_TOKEN_FILE_MISSING
#

http/error_schemas.ts view source

"token_file_missing" import {ERROR_TOKEN_FILE_MISSING} from '@fuzdev/fuz_app/http/error_schemas.js';

Bootstrap token file not found on disk.

ERROR_TOKEN_SCOPE_REQUIRED
#

http/error_schemas.ts view source

"token_scope_required" import {ERROR_TOKEN_SCOPE_REQUIRED} from '@fuzdev/fuz_app/http/error_schemas.js';

The credential is admitted on this channel, but the specific token's scope does not grant the requested capability.

The body carries required_scope: string in the stable <section>:<id> capability format — rpc:<method> for an action, surface:<name> for a non-RPC surface. Distinct from credential_type_required (which is about the *channel*) and from insufficient_permissions (about the *account's* roles): this one says the account could do it but this token was minted narrower.

ERROR_UNSUPPORTED_CONTENT_TYPE
#

http/error_schemas.ts view source

"unsupported_content_type" import {ERROR_UNSUPPORTED_CONTENT_TYPE} from '@fuzdev/fuz_app/http/error_schemas.js';

A POST whose Content-Type the route refuses: anything but application/json on a JSON route, a CORS-safelisted type or none on a raw_body one. See http/simple_request.ts.

ForeignKeyError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "foreign_key_violation"; } import {ForeignKeyError} from '@fuzdev/fuz_app/http/error_schemas.js';

Foreign key violation error — returned when a delete is blocked by references.

error

type "foreign_key_violation"

[key: string]

type unknown

NoActorsOnAccountError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "no_actors_on_account"; } import {NoActorsOnAccountError} from '@fuzdev/fuz_app/http/error_schemas.js';

error

type "no_actors_on_account"

[key: string]

type unknown

PayloadTooLargeError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "payload_too_large"; } import {PayloadTooLargeError} from '@fuzdev/fuz_app/http/error_schemas.js';

Payload too large error — returned when the request body exceeds the size limit.

error

type "payload_too_large"

[key: string]

type unknown

PermissionError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "insufficient_permissions"; required_roles: readonly string[]; } import {PermissionError} from '@fuzdev/fuz_app/http/error_schemas.js';

Permission error — returned by require_role() and the dispatcher's post-authorization role gate when the actor's role_grants don't include any of the route's auth.roles.

required_roles carries the full disjunction the route declared (auth.roles from the new flat-record shape). Single-role specs surface as a one-element array; multi-role disjunctions show every admittable role so clients can render targeted copy ("requires admin or steward").

error

type "insufficient_permissions"

required_roles

type readonly string[]

[key: string]

type unknown

RateLimitError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "rate_limit_exceeded"; retry_after: number; } import {RateLimitError} from '@fuzdev/fuz_app/http/error_schemas.js';

Rate limit error — returned when a rate limiter rejects the request.

error

type "rate_limit_exceeded"

retry_after

type number

[key: string]

type unknown

RateLimitKey
#

http/error_schemas.ts view source

value + type

"both" | "account" | "ip"

type "both" | "account" | "ip"

import {RateLimitKey} from '@fuzdev/fuz_app/http/error_schemas.js';

Rate limit key type — declares what a route or RPC action's rate limiter is keyed on.

  • 'ip' — per-IP rate limiting (login, bootstrap, password change, signup)
  • 'account' — per-account rate limiting. On REST auth routes the key is the submitted identifier (login). On RPC actions (post-auth) the key is the resolved actor id (request_context.actor.id) — separate namespace.
  • 'both' — both keys.

RouteErrorSchemas
#

http/error_schemas.ts view source

Partial<Record<number, ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>>>>

type Partial<Record<number, ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>>>>

import type {RouteErrorSchemas} from '@fuzdev/fuz_app/http/error_schemas.js';

Error schema map — maps HTTP status codes to Zod schemas.

Used on RouteSpec.errors and internally by derive_error_schemas.

[key: number]

type ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>> | undefined

TokenScopeRequiredError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "token_scope_required"; required_scope: string; } import {TokenScopeRequiredError} from '@fuzdev/fuz_app/http/error_schemas.js';

Token-scope error — returned by the require_token_scope guard (and its direct-call twin token_scope_surface_denial) when a narrowed api token reaches a capability its scope does not admit. See docs/security.md §Token scoping.

required_scope carries the capability string the route demands, verbatim from its auth.required_scope — surface:audit_stream for a non-RPC surface, rpc:<method> for a bridged action — matching the Rust token_scope_surface_denied_response and the dispatcher's own per-method denial. Third in the family with PermissionError and CredentialTypeRequiredError — each names what the route demanded rather than what the caller holds.

error

type "token_scope_required"

required_scope

type string

[key: string]

type unknown

UnsupportedContentTypeError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "unsupported_content_type"; } import {UnsupportedContentTypeError} from '@fuzdev/fuz_app/http/error_schemas.js';

Unsupported content type error — returned when a POST route refuses the request's Content-Type.

error

type "unsupported_content_type"

[key: string]

type unknown

ValidationError
#

http/error_schemas.ts view source

value + type

{ [x: string]: unknown; error: "invalid_request_body" | "invalid_json_body" | "invalid_route_params" | "invalid_query_params"; issues?: { [x: string]: unknown; code: string; message: string; path: (string | number)[]; }[] | undefined; } import {ValidationError} from '@fuzdev/fuz_app/http/error_schemas.js';

Input validation error — returned when params / query / body fails Zod parsing, or when the request body is not valid JSON.

error is one of the four validation codes the framework emits. issues carries Zod's validation issues for diagnostic display on the three schema-failure cases (invalid_request_body, invalid_route_params, invalid_query_params). The field is optional: the invalid_json_body case (request body parse failure or non-object root) emits no issues, and the schema-failure cases emit them only in development — production omits them (via dev_only) so error responses don't leak input-schema structure to callers.

error

type "invalid_request_body" | "invalid_json_body" | "invalid_route_params" | "invalid_query_params"

issues?

type { [x: string]: unknown; code: string; message: string; path: (string | number)[]; }[]

[key: string]

type unknown

Depends on
#

Imported by
#