Errors

REST and MCP share one error taxonomy and one status mapping — they cannot silently diverge on what a given error means.

Error shape

{
  "ok": false,
  "error": { "code": "NOT_FOUND", "message": "...", "details": { ... } }
}

Codes

CodeHTTP status
NOT_FOUND404
INVALID_ARGUMENT400
UNAUTHORIZED401
FORBIDDEN403
CONFLICT409
UNSUPPORTED422
INVARIANT_VIOLATION500
TEMPORARY_UNAVAILABLE503
RATE_LIMITED429
ENTITY_NOT_FOUND404
FACT_TOPIC_NOT_FOUND404
REALITY_NOT_RESOLVED404

Public discovery errors vs. resource privacy

ENTITY_NOT_FOUND, FACT_TOPIC_NOT_FOUND, and REALITY_NOT_RESOLVED are diagnostic on purpose — they tell you exactly which part of your request didn't resolve, or that it resolved but nothing has been observed yet. This is deliberately different from a Reality Lock you don't own, which always returns the same generic NOT_FOUND whether it doesn't exist or simply isn't yours — never enough detail to enumerate other principals' resources.

What you'll never see

An internal invariant violation is always returned as a generic INVARIANT_VIOLATION — its real underlying message is written only to AIality's own server-side structured log, never to the client.