shebang!

Error codes

Every error string the platform API, the agent-login flow, the OAuth decision endpoint, and the sherbase Data API gateway can return, by HTTP status and route.

Error codes

Most JSON error bodies carry an error field with one of the strings below. This table covers the platform API (/api/{platform,sherpage, sherserve,sherlink,sherbase,agent-login,oauth,mcp}/...) and the sherbase Data API gateway (/db/<slug>/...). See API reference for the shared 401/403 shapes and the WWW-Authenticate challenge every route uses.

One route doesn't yet fit this table: POST /api/platform/v1/keys (minting a key) puts a human-readable message directly in error for name/apps validation failures, rather than one of the stable codes below — for example "name must be between 1 and 60 characters" or "apps must be a non-empty array of page, serve, link, base". Match on HTTP status (400) and read error as prose here, not as a code. Stable codes for this route's validation failures are planned.

Code HTTP Where it occurs What to do
invalid_api_key 401 Any /v1/... route — missing, unrecognized, or revoked credential Send a valid shb_... key or sherlock bearer token in Authorization: Bearer.
invalid_token 401 Any /v1/... route — a JWT-shaped credential that failed verification Check error_description (token expired, unknown signing key, token issuer or audience mismatch, not an OAuth-obtained token, unknown or deleted client, client registry unavailable, malformed bearer token) and re-authenticate accordingly.
insufficient_scope 403 Any route — credential is valid but lacks the tier, apps scope, or project access the route requires Mint or use a key/client with the right scope, or get a project grant — see keys.
not_activated 403 Any /v1/... route, the hosted MCP, and POST /api/account/keys — the credential is valid but the account has not activated Activate at dash.shebang.pro, then retry. See activation.
captcha_failed 400 POST /api/account/activate — the Turnstile token was missing, expired, or rejected Reload the page and submit again; each token is single-use.
rate_limited 429 POST /api/account/activate — more than five attempts in a rolling 15 minutes Wait 15 minutes.
invalid_phone 400 POST /api/account/activate — the number did not parse Enter a valid number; Singapore numbers may be typed with or without +65.
not_eligible 400 POST /api/account/activate — the number is not on the invitation list, or is already bound to another account Check with Braven which number your invitation used.
already_activated 409 POST /api/account/activate — the account already has a number bound Nothing to do.
invalid_json 400 Most POST/PATCH routes across every service — request body isn't valid JSON Send a valid JSON body.
invalid_body 400 Platform routes (email, keys, projects, oauth-clients), POST /api/account/activate — body is JSON but missing/wrong-typed required fields Match the documented request-body shape for that route.
invalid_project 400 POST/PATCH /api/platform/v1/projects... — a project field fails validation (missing string field, bad color, bad oauth_client_id/status) Use the curated color palette and the documented field types.
invalid_slug 400 POST/PATCH /api/platform/v1/projects..., POST /api/sherbase/v1/databases — slug fails the format check Use 3–30 lowercase letters/numbers/underscores.
slug_taken 409 POST/PATCH /api/platform/v1/projects... — slug already used by another project Pick a different slug.
slug_conflict 409 POST /api/sherpage/v1/pages, POST /api/sherserve/v1/objects — slug already used by another page/object Pick a different slug.
alias_conflict 409 PATCH/DELETE on a sherpage page, sherserve object, or sherlink link — the requested short-link alias is taken Pick a different alias.
password_required 400 Setting access: "password" on a page, object, or link with no password given Supply a password.
public_id_exhausted 500 POST /api/sherpage/v1/pages, POST /api/sherserve/v1/objects — the random public-id space couldn't find a free id Retry the call.
profile_handle_missing 500 Any sherpage/sherserve route that needs the caller's profile handle and finds none Server-side data issue — retry, and report if it persists.
storage_cleanup_failed 500 DELETE on a sherpage page, sherserve object, or sherlink link — the record was removed but its stored files weren't The resource is gone from listings; retry isn't meaningful — report if seen.
link_cleanup_failed 500 DELETE on a sherpage page, sherserve object, or sherlink link — the record was removed but its short link wasn't Same as storage_cleanup_failed — report if seen.
invalid_multipart_body 400 POST /api/sherserve/v1/objects — malformed multipart upload Fix the multipart body (a valid file part with a filename).
invalid_resource_type 400 POST /api/platform/v1/projects/{id}/assign and /unassign Name one of the documented resource types.
client_already_attached 409 PATCH /api/platform/v1/projects/{id} — the named OAuth client already has a home project Detach it from its current project first, or pick a different client.
project_not_empty 409 DELETE /api/platform/v1/projects/{id} — the project still holds resources Move or delete its resources first.
last_project 409 DELETE /api/platform/v1/projects/{id} — this is the account's only remaining project An account must keep at least one project.
cannot_revoke_current_key 400 DELETE /api/platform/v1/keys/{id} — the target is the key authenticating this call Revoke it from a different key, or from the dashboard's account page.
forbidden 403 /api/platform/v1/oauth-clients — caller isn't a master key Use a master key.
invalid_email_input 400 POST /api/platform/v1/email — bad recipient, subject, or body Fix the email fields.
email_quota_exceeded 429 POST /api/platform/v1/email — over 10 sends/account/24h Wait until the returned retry_after_hours elapses — see limits.
send_failed 502 POST /api/platform/v1/email — the upstream send provider rejected it Check the error's message; retry later.
data_api_disabled 409 POST /api/sherbase/v1/databases/{slug}/reload — no gateway instance registered for this slug Enable the Data API on this database first.
data_api_not_enabled 400 POST /api/sherbase/v1/databases/{slug}/secret — Data API was never enabled Call the enable route first.
not_found 404 Any {slug}/{id} route — no matching resource for this credential Check the identifier and that this credential can reach it.
mfa_required 403 POST /api/oauth/decision, POST /api/agent-login/decision — second factor not yet satisfied this session Complete the account's second factor, then retry.

Device login (/api/agent-login/...), RFC 8628 shapes

These use error the same way but follow RFC 8628's device-flow error set. See device login.

Code HTTP Where it occurs What to do
invalid_request 400 device_authorization, token — malformed body or missing required field Fix the request body.
rate_limited 429 device_authorization, token — too many requests from one client IP Back off and retry.
unsupported_grant_type 400 tokengrant_type isn't the device-code grant Use urn:ietf:params:oauth:grant-type:device_code.
authorization_pending 400 token — the user hasn't approved yet Keep polling at the returned interval.
slow_down 400 token — polling faster than the given interval Poll at the larger interval this response returns.
access_denied 400 token — the user denied the request Start the device flow again.
expired_token 400 token — the device code's 10-minute lifetime elapsed Start the device flow again.
invalid_grant 400 token — the device code is unknown or already claimed Start the device flow again.

Uncaught server errors

Code HTTP Where it occurs What to do
internal_error 500 Any route's catch-all handler for an unexpected server-side failure Retry; report if it persists.

The sherbase Data API gateway (/db/<slug>/...)

The gateway answers every error Supabase-shaped ({message, code, hint, details}), with code set to the HTTP status as a string rather than a named error like the routes above:

HTTP Message What it means
401 No API key found in request / Invalid API key Missing or unrecognized apikey/Bearer credential for this database.
404 database not found / Not found Unknown slug, or a path that isn't /rest/v1/* or /auth/v1/*.
503 database starting The database's PostgREST instance is still coming up — retry shortly.
502 upstream unavailable PostgREST or sherlock didn't respond — retry.
500 internal error Unexpected gateway failure — report if it persists.

Next

Limits — the numeric caps behind email_quota_exceeded and a few of the errors above.