MemClaw / docs
Reference

Errors and Status Codes

The canonical error envelope shared by REST and MCP, plus the HTTP status → code mapping.

Both REST and MCP emit the same error shape. Source: core-api/src/core_api/errors.py (added in PR #58).

Canonical envelope

{
  "error": {
    "code": "<UPPER_SNAKE>",
    "message": "<human-readable>",
    "details": { "...": "optional" }
  }
}

Dispatch on error.code — it's the machine-readable signal and is identical across both surfaces.

REST back-compat

REST responses keep a top-level detail field alongside error so existing clients reading response.json()["detail"] keep working:

{
  "detail": "Memory not found",
  "error": { "code": "NOT_FOUND", "message": "Memory not found" }
}

detail is the deprecated mirror. New clients should switch to error.code.

For FastAPI request-validation failures (422), detail is the original list of validation errors and error.details.errors carries the same list aggregated.

MCP envelope

MCP tools return the same error envelope, JSON-serialized, plus _latency_ms:

{
  "error": {
    "code": "INVALID_ARGUMENTS",
    "message": "Unknown op 'wat'.",
    "details": { "op": "wat", "expected_ops": ["read", "update", "..."] }
  },
  "_latency_ms": 7
}

Pre-PR-#58 MCP tools returned bare "Error (XXX): ..." strings — that format is gone.

HTTP status → canonical code

From STATUS_TO_CODE in errors.py:

StatusCode
400BAD_REQUEST
401UNAUTHORIZED
402PAYMENT_REQUIRED
403FORBIDDEN
404NOT_FOUND
405METHOD_NOT_ALLOWED
408REQUEST_TIMEOUT
409CONFLICT
410GONE
413PAYLOAD_TOO_LARGE
415UNSUPPORTED_MEDIA_TYPE
422INVALID_ARGUMENTS
429RATE_LIMITED
500INTERNAL_ERROR
501NOT_IMPLEMENTED
502UPSTREAM_ERROR
503UNAVAILABLE
504UPSTREAM_TIMEOUT

Statuses not in the table fall back to HTTP_<status> (e.g. HTTP_418).

Trust-level errors

Trust failures come from core_api.services.trust_service.parse_trust_error and are re-wrapped as canonical FORBIDDEN with the required vs. caller's level in details.

Idempotency

The write route (POST /api/v1/memories) accepts an Idempotency-Key header (IDEMPOTENCY_HEADER in core-api/src/core_api/middleware/idempotency.py). A retry within the cache window with the same key short-circuits to the original response without consuming a write slot.