Sonny Labs Docs
Error codes

Error codes

Stable dot-namespaced identifiers returned in the RFC 9457 Problem envelope's `code` field. Branch on these in your SDK exception handlers.

Every error response from the Sonny Labs API is an RFC 9457 application/problem+json envelope with a stable, dot-namespaced code field. The type URL on the envelope points back to one of the pages below — branch on code in your SDK exception handlers, not on title or detail.

CodeHTTPSummary
auth.api_key.expired401The API key authenticated correctly but its expires_at is in the past.
auth.forbidden403The principal is authenticated but is not allowed to perform this operation.
auth.forbidden_scope403The credential is valid but does not carry the scope this operation requires.
auth.no_org_context400The request authenticated but no org_id was bound to the session — typically a misconfigured caller.
auth.scope.insufficient403Backend variant of auth.forbidden_scope emitted by the scope-enforcement filter.
auth.scope.missing403Alias of auth.scope.insufficient retained for SDK dispatch compatibility.
auth.token.invalid401A credential was supplied but failed signature, format, or expiry validation.
auth.unauthenticated401The request reached an authenticated endpoint without a credential the server could verify.
http.403403Generic 403 emitted when a controller throws ResponseStatusException(FORBIDDEN) without a more specific code.
idempotency.key_reuse_mismatch409The same Idempotency-Key was reused with a different request body.
invites.already_member409The accepting user is already a member of the target organisation.
invites.email_mismatch403The accepting user's email does not match the email the invite was issued for.
invites.expired410The invite token is past its expires_at and is no longer valid.
invites.not_found404The invite token is unknown to the server, or has been revoked.
invites.principal_email_unavailable403The accepting principal's WorkOS profile did not return an email — required for the invite-email match check.
onboarding.already_in_org409The signed-in user attempted to create a new org while already belonging to one.
onboarding.unsupported_in_self_hosted501Org-creation is disabled in self-hosted deployments — the operator provisions orgs out of band.
org.not_provisioned409The principal is authenticated but no auth.organizations row has been provisioned for their org yet.
resource.not_found404The path matched no route or the requested entity does not exist (or is not visible to this principal).
scans.invalid_param400A query parameter on the scans endpoints failed validation.
scans.not_found404The scan id did not resolve in the principal's org.
service.not-ready503The backend received a request before its readiness probe transitioned to ready.
tenant.quota_exceeded429The organisation has exceeded a billing or fair-use quota for the requested operation.
upstream.unavailable502, 503A downstream dependency the dashboard or backend relies on is unreachable.
users.invalid_cursor400The opaque pagination cursor on /v1/users could not be decoded.
users.invalid_param400A query parameter on the users endpoints failed validation.
validation.body_invalid400Request body parsed as JSON but failed bean-validation rules.
validation.body_unparseable400Request body could not be parsed as JSON at all.
validation.error400Generic 400 surfaced when a request fails ad-hoc validation that is not bucketed into a more specific code.
validation.invalid_json400Dashboard BFF variant emitted when a v1 proxy request body is not valid JSON.
validation.parameter_invalid400A query or path parameter failed bean-validation rules.
validation.parameter_missing400A required query or path parameter was not supplied.
validation.parameter_type_mismatch400A query or path parameter could not be converted to the expected type.

Namespaces

  • auth.* — credential rejected, scope missing, session expired.
  • validation.* — request body / parameter failed validation.
  • resource.* — path or entity not found in the principal's org.
  • idempotency.*Idempotency-Key collision.
  • scans.* — scan-specific 4xx (controller-local validation).
  • upstream.* — downstream dependency unreachable; safe to retry.
  • tenant.* — billing / quota exhaustion.
  • invites.*, onboarding.*, org.*, users.* — auth-domain 4xx not covered by the broad auth.* namespace.
  • service.* — readiness / liveness probe failures during boot.
  • http.* — fallback synthesised when a controller throws ResponseStatusException without a typed code.

SDK exception mapping

The SDKs dispatch on code first, then fall back to HTTP status:

NamespacePython SDKTypeScript SDK
auth.*AuthenticationErrorAuthenticationError
validation.*ValidationErrorValidationError
idempotency.*IdempotencyConflictErrorIdempotencyConflictError
403 (any)ScopeMissingErrorScopeMissingError
404 (any)NotFoundErrorNotFoundError
429 (any)RateLimitErrorRateLimitError
5xx (any)ServerErrorServerError

See the Python SDK quickstart and TypeScript SDK quickstart for the full dispatch tables.

On this page