Skip to main content
Memory Crystal returns structured error responses for all failure modes. This page maps HTTP status codes to specific error conditions and shows how to diagnose them.

HTTP Status Codes

400 Bad Request

The request was malformed or missing required parameters. Common causes:
  • Missing required JSON fields
  • Invalid JSON syntax
  • Empty query string
  • Invalid UUID format for memory/KB IDs
Example response:
{
  "error": "Bad request",
  "details": "Missing required field: query"
}
How to debug:
  • Check request body matches endpoint schema
  • Validate JSON with jq before sending
  • Verify all required parameters are present

401 Unauthorized

Authentication failed. The API key is missing, invalid, or expired. Common causes:
  • Missing Authorization header
  • Malformed header (not Bearer <token>)
  • Bearer token doesn’t match any key hash in the database
  • Key is inactive (user disabled it)
  • Key has expired
Example response:
{
  "error": "Unauthorized"
}
How to debug:
# Check if key is in the header
curl -v https://your-deployment/api/mcp/recall \
  -H "Authorization: Bearer $MEMORY_CRYSTAL_API_KEY"

# Verify the key is not truncated or typo'd
echo $MEMORY_CRYSTAL_API_KEY | wc -c  # Should be 65 chars (64 hex + newline)

# Test with a new key if you suspect expiration

403 Forbidden

Authentication succeeded but the user is not allowed to access this resource. Common causes:
  • Memory belongs to a different user
  • Knowledge base belongs to a different user
  • User’s tier doesn’t support this operation
  • Channel scope mismatch (memory in channel A, user in channel B)
Example response:
{
  "error": "Forbidden"
}
How to debug:
  • Verify the resource ID belongs to the authenticated user
  • Check user tier restrictions (Free vs Pro vs Ultra)
  • Confirm channel scope if applicable

429 Too Many Requests

Rate limit exceeded for the user’s tier. Common causes:
  • Burst of requests exceeding per-minute limit
  • Multiple API keys hitting the same tier bucket
  • Bot or automation hitting limits
  • Shared API key across team members
Response headers:
Retry-After: 45
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1681234567
Example response:
{
  "error": "Rate limit exceeded",
  "retryAfterMs": 45000
}
How to debug:
# Check remaining quota
curl -I https://your-deployment/api/mcp/stats \
  -H "Authorization: Bearer $API_KEY" | grep X-RateLimit

# Back off and retry with exponential backoff
sleep 45
curl https://your-deployment/api/mcp/recall \
  -H "Authorization: Bearer $API_KEY"
See Rate Limits for tier-specific limits and recovery strategies.

500 Internal Server Error

An unexpected error occurred on the server. Common causes:
  • Database connection failure
  • Embedding service timeout
  • Uncaught exception in endpoint handler
  • Convex backend unavailability
Example response:
{
  "error": "Internal server error",
  "requestId": "req_12345"
}
How to debug:
  • Note the requestId and report it to support
  • Check server logs (if you have access)
  • Verify Convex deployment is healthy
  • Retry after a short delay (transient failures)

Memory Blocking Errors

Some memories may be blocked from being written or recalled due to content policy violations.

Memory Blocked on Write

When crystal_remember fails to save a memory:
{
  "error": "Memory blocked: [reason] [[threatId]]"
}
Possible reasons:
  • violent_content — memory contains instructions for harm
  • illegal_activity — memory documents illegal actions
  • personal_info_exposure — memory exposes PII without consent
  • copyright_violation — memory reproduces copyrighted text
How to debug:
  1. Review the memory content
  2. Remove the flagged content
  3. Rewrite with more general language
  4. Contact support if you believe it’s a false positive (include threatId)

Memory Blocked on Recall

Blocked memories are silently filtered from search results. You won’t see an error, but some expected memories won’t appear. How to debug:
# Query stats to see total count
curl https://your-deployment/api/mcp/stats \
  -H "Authorization: Bearer $API_KEY" | jq .memoryCount

# If count is higher than recall results, some are filtered
# Check recent memories to see if they're blocked:
curl -X POST https://your-deployment/api/mcp/recent-messages \
  -H "Authorization: Bearer $API_KEY" \
  -d '{"limit": 100}'

Embedding and Deduplication Errors

Embedding Service Timeout

The embedding service (Google Gemini or OpenAI) didn’t respond within timeout.
{
  "error": "Embedding service timeout",
  "details": "Please retry after a few seconds"
}
How to debug:
  • Retry after 5–10 seconds
  • Check if embedding provider status page shows outages
  • Check that OPENAI_API_KEY or Gemini credentials are valid
  • If persistent, contact support

Deduplication Conflict

A memory with identical content already exists.
{
  "error": "Duplicate memory",
  "existingMemoryId": "mem_456",
  "details": "A memory with the same content already exists"
}
How to debug:
  • Decide: use the existing memory or update it with crystal_edit
  • Or create a new memory with slightly different wording
  • The existingMemoryId can be used with crystal_trace to see context

Knowledge Base Errors

Knowledge Base Not Found

Referenced KB ID doesn’t exist or belongs to a different user.
{
  "error": "Knowledge base not found"
}

Import Batch Too Large

Chunk import batch exceeds size limits.
{
  "error": "Import batch too large",
  "details": "Maximum 10,000 chunks per import, got 15,000"
}
How to fix:
  • Split into multiple import requests
  • Combine related chunks before importing

Invalid Chunk Metadata

Chunk structure doesn’t match expected schema.
{
  "error": "Invalid chunk",
  "index": 5,
  "details": "Missing required field: metadata.title"
}
How to fix:
{
  "chunks": [
    {
      "content": "...",
      "metadata": {
        "title": "Document Title",        // Required
        "sourceUrl": "https://...",       // Recommended
        "chunkIndex": 0,                  // Optional but helps with ordering
        "totalChunks": 1                  // Optional
      }
    }
  ]
}

Debugging Checklist

When something fails:
  1. Check authentication:
    curl -X GET https://your-deployment/api/knowledge-bases \
      -H "Authorization: Bearer $MEMORY_CRYSTAL_API_KEY"
    
  2. Verify endpoint is correct:
    • Recall: POST /api/mcp/recall
    • Remember: POST /api/mcp/capture
    • Stats: GET /api/mcp/stats
  3. Validate request body:
    cat request.json | jq . > /dev/null  # Check JSON syntax
    
  4. Test with minimal request:
    curl -X POST https://your-deployment/api/mcp/stats \
      -H "Authorization: Bearer $API_KEY" \
      -H "Content-Type: application/json" \
      -d '{}'
    
  5. Check rate limits:
    curl -I https://your-deployment/api/mcp/stats \
      -H "Authorization: Bearer $API_KEY" | grep X-RateLimit
    
  6. Enable verbose logging:
    curl -v https://your-deployment/api/mcp/recall \
      -H "Authorization: Bearer $API_KEY" \
      -d '{"query": "test", "limit": 1}'
    

Getting Help

If you’ve gone through the checklist:
  1. Save the full error response (redact API keys)
  2. Note your requestId from the response header
  3. Include your tier/plan
  4. Report to support with a minimal reproduction case