Limits and troubleshooting
Error format, common status codes, troubleshooting steps and known limitations of Agent Memory.
Error format
General API errors return application/problem+json:
{
"title": "precondition_failed",
"status": 412,
"detail": "the memory changed since it was read; re-read it and retry with the current version",
"code": "precondition_failed",
"traceId": "08c347b2e6d1daa99bd11f09db5b54cd",
"currentVersion": 1466771
}traceId is useful in support requests. Authentication errors (401), missing permissions (403) and invisible resources (404) may return without a body. MCP tools return errors as Error: … text.
Common codes
| Status / code | Cause | What to do |
|---|---|---|
401 | Key missing, invalid, expired or revoked. | Check the key in the console. |
403 (no body) | The key lacks the required permission (e.g. delete, share). | Recreate the key with the right permissions. |
403 policy_denied (identity-binding) | An agentId the key isn't bound to was sent, or userId was sent without the act for users permission. | Remove agentId; if you act on behalf of users, enable the permission. |
403 policy_denied | Policy denial, e.g. sharing a memory you don't own. | |
403 TENANT_SUSPENDED | The organization is suspended or closing (writes are disabled). | Contact your admin. |
404 | Workspace/application/memory doesn't exist or isn't visible to you. Another workspace's ID also returns 404. | Check that workspaceId is your key's workspace. |
400 VALIDATION_FAILED | Invalid field (e.g. unknown type, mode, visibility, sourceKind). | Read the detail field. |
409 IDEMPOTENCY_CONFLICT | The same Idempotency-Key was used with a different body. | Use a new key for each distinct operation. |
409 deletion_blocked_by_active_dependents | Live memories derived from the one being deleted exist. | Review blockingDependents; use cascade=true deliberately. |
409 concurrent_update | Concurrent write race. | Re-read and retry. |
412 precondition_failed | The If-Match version is stale. | Retry with currentVersion. |
413 | Request body larger than 1 MiB. | Split the content. |
422 CONTEXT_BUDGET_TOO_SMALL | The token budget can't even hold the admin rules. | Increase tokenBudget (requiredTokens). |
400 RECEIPT_MISMATCH | Feedback marks as "used" a memory the receipt didn't deliver. | Use the same runId and receipt. |
429 QUOTA_EXCEEDED / RATE_LIMITED | Monthly operation, storage or key-count quota, or rate limit. | Wait for Retry-After; check your plan. |
503 TENANT_MAINTENANCE / PLACEMENT_UNAVAILABLE / OVERLOADED / UPSTREAM_UNAVAILABLE | Maintenance, data placement not ready, overload, or LLM/embedding provider unreachable. | Retry after Retry-After. |
Troubleshooting
I wrote it but it doesn't show up in search.
- Did you send
layer: "Workspace"in REST? Without it, the memory isn't durable. - Is the memory of type
artifact_ref? This type isn't returned in search; read it withget_memory. - Is the memory
private/uservisibility, and are you searching as a different agent/user? - Did you use a different
applicationIdor afacet/tagsfilter? - The memory may have been quarantined (content screening); check in the console.
- The
hashingembedding (the self-hosted default) doesn't do semantic matching; if the query and the memory use different words, it may not be found. Useonnxor another semantic provider. - If
validFromis in the future orvalidTois in the past, the memory isn't returned by default search.
I wrote the same information twice and there's only one memory. Expected behavior: the duplicate check merges memories (merged: true).
An old decision still shows up. Write the new memory with supersedes or use supersede_memory; consolidation only automatically supersedes very similar decisions.
The operation status stays pending. Follow-up jobs (event notification, deferred embedding) may be waiting; the memory can be read in the meantime. If it takes long, check that background jobs (Hangfire) are running.
Consolidation extracted no facts / only simple ones. Without a configured LLM, extraction is rule-based. See Configuration.
Idle runs aren't consolidated automatically. The maintenance service runs only in the background host or with MemoryMaintenance__Host=api.
Known limitations
| Area | Limitation |
|---|---|
| Writing | LLM extraction doesn't happen at write time, only during consolidation. There is no separate public endpoint that takes a raw message list (except the console playground). |
| Search | Tag filters are exact match + AND only. Natural-language time expressions aren't interpreted. Reranking is LLM-only. Full-text search is not BM25. |
| Time | Expiry can't be set from the public API. As-of reads aren't available in MCP; historical text can't be searched. |
| Access | classification doesn't affect access. Source system permissions aren't synchronized. tenant visibility doesn't move memories outside the workspace. |
| Entities | Entities are extracted only during consolidation; there is no API for entity-to-entity relations or entity-centric search. |
| Files | File summarization accepts text only ({path: content}, at most 50 files per request); PDFs, images and audio aren't processed, and files aren't chunked for search. |
| Deletion | Deleting a single memory doesn't clean entity names or episode summaries; there is no bulk per-user deletion. |
| SDK | No consolidation or block operations in Node/Python; Python is sync only; packages aren't published to public registries. |
| Compatibility | There is no proxy/compatibility layer in the OpenAI chat API format; memory is used through its own API, MCP or the SDKs. |
| Command line | There is no separate CLI tool; administration is done through the console, REST and host commands (--migrate, --bootstrap-key …). |