Errors

Error codes and troubleshooting.

Spectron uses standard HTTP status codes and follows RFC 7807 Problem Details for all error responses.

All errors return a JSON body with the following fields:

{
"type": "https://spectron.dev/errors/context-not-found",
"title": "Context not found",
"status": 404,
"detail": "No context with id 'acme-staging' exists on this server.",
"instance": "/api/v1/contexts/acme-staging"
}
FieldDescription
typeA URI identifying the error type. Stable across versions.
titleA short, human-readable summary of the problem type.
statusThe HTTP status code.
detailA human-readable explanation specific to this occurrence.
instanceThe request path that produced the error.

The request body or query parameters are invalid. Common causes:

  • Malformed JSON body

  • Missing required fields

  • Invalid field values (e.g. unknown mode for knowledge query)

  • Scope floor violation (requesting a scope narrower than the key's floor)

{
"type": "https://spectron.dev/errors/validation-error",
"title": "Validation error",
"status": 400,
"detail": "Field 'mode' must be one of: vector, bm25, hybrid, hybrid_graph. Got: 'fuzzy'.",
"instance": "/api/v1/acme-prod/query"
}

No Authorization: Bearer token was provided, or the key is malformed.

{
"type": "https://spectron.dev/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "API key missing. Include 'Authorization: Bearer <key>' in your request.",
"instance": "/api/v1/acme-prod/sessions"
}

The API key is valid but does not have permission to perform this operation. Common causes:

  • Agent key attempting a management operation

  • Key's scope floor does not include the requested scope

  • Agent key attempting to persist a reflection (requires supervisor principal)

{
"type": "https://spectron.dev/errors/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "This operation requires a management key. The provided key has principal 'agent'.",
"instance": "/api/v1/contexts"
}

The requested resource does not exist.

{
"type": "https://spectron.dev/errors/not-found",
"title": "Not found",
"status": 404,
"detail": "No document with id 'document:0197d8f2...' exists in context 'acme-prod'.",
"instance": "/api/v1/acme-prod/documents/0197d8f2"
}

A resource with the same identifier already exists, or an idempotency conflict occurred:

  • Duplicate Context id on create

  • Same Idempotency-Key with a different request body on /facts or /facts/batch

  • Duplicate idempotency request while the first is still in flight

{
"type": "https://spectron.dev/errors/conflict",
"title": "Conflict",
"status": 409,
"detail": "A context with id 'acme-prod' already exists.",
"instance": "/api/v1/contexts/acme-prod"
}

The uploaded file exceeds the per-Context size limit.

{
"type": "https://spectron.dev/errors/payload-too-large",
"title": "Payload too large",
"status": 413,
"detail": "Uploaded file size (52.4 MB) exceeds the per-context limit (50 MB).",
"instance": "/api/v1/acme-prod/documents"
}

The request is syntactically valid but semantically invalid.

{
"type": "https://spectron.dev/errors/unprocessable",
"title": "Unprocessable entity",
"status": 422,
"detail": "Cannot bind context to namespace 'spectron' – this namespace is reserved for internal use.",
"instance": "/api/v1/contexts/test"
}

The Context has exceeded its token budget or rate limit. Applies to LLM-backed paths including /chat, /facts?infer=full, /reflect, and /consolidate — not to read-only cache hits or direct lookups.

{
"type": "https://spectron.dev/errors/rate-limited",
"title": "Too many requests",
"status": 429,
"detail": "Monthly token limit of 1,000,000 has been reached for context 'acme-prod'.",
"instance": "/api/v1/acme-prod/sessions/sess_abc/turns",
"retry_after": null
}

An unexpected error occurred server-side. The detail field contains a request ID for support escalation.

{
"type": "https://spectron.dev/errors/internal",
"title": "Internal server error",
"status": 500,
"detail": "An unexpected error occurred. Request ID: req_01HF3X...",
"instance": "/api/v1/acme-prod/context"
}

The server is temporarily unable to handle requests – typically during a SurrealDB connection issue or startup.

ExceptionHTTP statusWhen
SpectronAuthError401Missing or invalid API key
SpectronScopeError403Scope floor or principal rejects the call
SpectronNotFoundError404Resource does not exist
SpectronAPIErrorOther non-2xxGeneric API failure (includes 400, 409, 429, 5xx)
from surrealdb import SpectronNotFoundError, SpectronAPIError

try:
doc = await client.documents.get("document:nonexistent")
except SpectronNotFoundError as e:
print(f"Document not found: {e.message}")
except SpectronAPIError as e:
if e.status_code == 429:
print(f"Rate limit exceeded: {e.body}")

See Errors and retries for the full hierarchy and retry behaviour.

Error classHTTP statusWhen
AuthError401Missing or invalid API key
ScopeError403Scope floor or principal rejection
NotFoundError404Resource does not exist
ValidationError400, 422Invalid request payload
RateLimitError429Token or rate limit exceeded
ServerError500, 503Server-side failure
ConnectionErrorNetwork failure or timeout
import { NotFoundError, RateLimitError } from "@surrealdb/spectron";

try {
const doc = await client.documents.get("document:nonexistent");
} catch (e) {
if (e instanceof NotFoundError) {
console.error("Document not found:", e.detail);
} else if (e instanceof RateLimitError) {
console.error("Rate limit exceeded");
}
}

Documents that fail during async processing do not return HTTP errors – they set the document status to "failed" and populate the error field:

{
"id": "document:0197d8f2...",
"status": "failed",
"error": "PDF extraction failed: file is encrypted and no password was provided.",
"processing_started_at": "2026-05-12T14:22:11Z",
"processing_completed_at": "2026-05-12T14:22:14Z"
}

Poll GET /api/v1/{context_id}/documents/{id} to check document status. See Uploading documents for retry guidance.

MCP tool failures use a different envelope from REST, but carry the same HTTP status semantics:

  • Operation failuresisError: true tool result with structuredContent.error.status (404, 403, 429, etc.). The JSON-RPC transport returns HTTP 200.

  • Protocol faults → JSON-RPC error (bad params, unknown tool).

Auth failures and missing Contexts are masked as 401, never 404, so unauthenticated callers cannot enumerate Context ids. See MCP tools.

Was this page helpful?