@gram 2 doc portal-reference-mcp-errors t MCP errors and write recovery d Structured failures, CAS, receipts, retries and mount-specific recovery. view document ::rich # MCP errors and write recovery ## Response model MCP `tools/call` failures return tool-level results with `isError` and structured `error:{code,message,...details}`; these are distinct from JSON-RPC transport/protocol errors. The desktop helper separately returns JSON-RPC `-32000` with `data.code: E_APP_NOT_RUNNING` for an unavailable app or JSON-RPC `-32603` when HTTP has no body. Success commonly includes structured content and text content. There is no official per-tool output JSON Schema: consult each tool's documented source-grounded result contract, and treat optional fields as conditional. The compact response budget is 16,384 bytes. ## Exact operational codes | Code | Meaning and action | |---|---| | `E_ARGUMENT` | Invalid/missing input, unknown key, selector conflict, or invalid cursor/limit. Correct the request; do not retry unchanged invalid input. | | `E_PATH` | Path is outside an allowed local folder/mount. Use the exact mount key from `gram_projects`; never substitute its display name. | | `E_READ_ONLY` | Approval or mount is read-only. Reads may continue; a write requires an already-authorized writable scope. | | `STALE_READ` | Document moved during historical read. Read again at current state. | | `STALE_CURSOR` | Cursor is bound to another document/revision/section. Get a fresh page/read cursor. | | `E_CURSOR` | Cursor malformed. Obtain a replacement from the corresponding listing/read. | | `E_REQUEST_REUSE` | The same ID is bound to a different intent. Do not retry the changed request under that ID; retry the original exact intent only to replay it, or use a new ID for a new intent. | | `COMMIT_UNKNOWN` | Replacement was published but durability is uncertain. Retry only the identical patch with the same request ID; inspect persisted state before claiming success. | | `STORAGE_CONFLICT` | Cloud provider state conflicted. Re-read persisted state before composing a new write. | | `PROVIDER_AUTH_REQUIRED` | Provider authorization is needed. No successful remote write is implied. | | `E_STORAGE` | Storage commit failed. Inspect receipt and sync status, then re-read before retrying. | | `E_INTEGRITY` | History sequence/hash audit failed. Core rejects writes to corrupt history; do not repair by editing the trailer. | | `E_MIGRATION` | Legacy data cannot be converted by the requested path. Preserve source and use the supported migration contract. | Other source-defined errors include `E_CORE_UNAVAILABLE`, `E_TIMEOUT`, `E_CORE`, `E_INTERNAL`, `E_UNKNOWN_TOOL`, `E_CONTEXT_BUDGET`, `E_TOO_MANY_DOCUMENTS`, `E_TIME_NOT_RECORDED` and `E_REQUEST_ID`. Read the returned code/details; codes are not interchangeable. ## Safe CAS sequence 1. Read current document identity `{path,rev,hash}`. 2. Prepare one intended patch with that revision/hash, a unique 1–128-character request ID, and nonempty operations. 3. The public tools expose no receipt tool. For an uncertain `gram_patch`, resend the exact same request_id and unchanged path, base_revision, expected_hash, and operations; Core replays the original receipt. 4. If Core reports stale/CAS conflict, reread and rebase the human intent on the new content; send a new request ID. 5. On mounted cloud writes, verify returned `sync.state: synced`; successful MCP completion alone is not the remote persistence check. A request_id binds canonical intent, including document ID, operation, base_revision, expected_hash, operations, effective_at, and context. An A-to-B-to-A reversal has a different CAS base and is a different intent, so reusing the first ID returns E_REQUEST_REUSE. ## Create and retry boundaries `gram_create` has no request_id. If its response is uncertain, read the target path before further action. Creating at an existing path returns `STALE_REVISION` with `Create target already exists`; do not treat it as a patch or overwrite. Only retry `gram_patch` by resending the exact same request_id and complete intent. The public MCP API has no standalone receipt tool. The shortened displayed hash maps to a full artifact hash held by the caller's gateway; if a short hash is no longer resolvable, reread rather than guessing. ## Local/cloud boundary Local document tools require the app's approved vault scope; profile and capabilities are available without document approval. Read-only approvals reject create/patch. Cloud tools open a caller-scoped workspace, use exact mount paths, and commit back to the provider. Cloud capability reports semantic search unavailable and `auto` uses lexical fallback; local semantic behavior is runtime-probed. Local mount sync may be pending; cloud successful writes report synced. No tool bypasses the caller's existing authority. ## Exact source-backed error messages | Surface | Code | Actual message | Sources | |---|---|---|---| | MCP tool result | `E_ARGUMENT` | `Unknown argument ` | thegram-vault/internal/mcp/gateway.go#335359731a3724bb0bf7a02093e3d7e1bbd93ccda3bbdff143b6178eec98a436 | | MCP tool result | `E_CURSOR` | `Invalid list cursor` | thegram-vault/internal/mcp/tools_common.go#f243590ff0ab46a241c752ae104c538e5064c869525209dfc7219572d6d5523c | | MCP tool result | `E_CURSOR` | `Invalid section cursor` | thegram-vault/internal/mcp/memory.go#cf97b451501c97d5db3c43836171a65ce221b9105d1b3c75ae58ccefc93e72e1 | | MCP tool result | `E_CURSOR` | `Invalid changes cursor` | thegram-vault/internal/mcp/memory.go#cf97b451501c97d5db3c43836171a65ce221b9105d1b3c75ae58ccefc93e72e1 | | MCP tool result | `E_CURSOR` | `Invalid context cursor` | thegram-vault/internal/mcp/tools_entity.go#04d41ed2634d5904fa812be53c92c70a06403d78334890b9791c168b8f89c9f0 | | MCP tool result | `E_CURSOR` | `Invalid state cursor` | thegram-vault/internal/mcp/tools_history.go#c2d2b98e94a1cebbc9aadae0e931500c109b61fe44e90ad2f9e1bc6b76e499c8 | | desktop JSON-RPC -32000 | `E_APP_NOT_RUNNING` | `Thegram is not running. Open the Thegram app, then retry.` | thegram-desktop/Helper/ThegramMCP.swift#87b7fdb6a576da59e84d86ae32624e452f5da7e3c4138b6f539374437556e6dd | | desktop JSON-RPC | `JSON-RPC -32603` | `Thegram answered HTTP \(response.status) with no body` | thegram-desktop/Helper/ThegramMCP.swift#87b7fdb6a576da59e84d86ae32624e452f5da7e3c4138b6f539374437556e6dd | | MCP tool result | `STALE_READ` | `The document changed while it was read; read again` | thegram-vault/internal/mcp/tools_common.go#f243590ff0ab46a241c752ae104c538e5064c869525209dfc7219572d6d5523c | | MCP tool result | `STALE_READ` | `The document was replaced while it was read` | thegram-vault/internal/mcp/tools_history.go#c2d2b98e94a1cebbc9aadae0e931500c109b61fe44e90ad2f9e1bc6b76e499c8 | | MCP tool result | `STALE_CURSOR` | `The documents changed since this cursor; list again` | thegram-vault/internal/mcp/tools_common.go#f243590ff0ab46a241c752ae104c538e5064c869525209dfc7219572d6d5523c | | MCP tool result | `STALE_CURSOR` | `The documents changed since this cursor; ask again without cursor` | thegram-vault/internal/mcp/memory.go#cf97b451501c97d5db3c43836171a65ce221b9105d1b3c75ae58ccefc93e72e1 | | MCP tool result | `STALE_CURSOR` | `Cursor belongs to another document or revision` | thegram-vault/internal/mcp/tools_history.go#c2d2b98e94a1cebbc9aadae0e931500c109b61fe44e90ad2f9e1bc6b76e499c8 | | MCP tool result | `STALE_CURSOR` | `The cursor belongs to another document, revision or section` | thegram-vault/internal/mcp/memory.go#cf97b451501c97d5db3c43836171a65ce221b9105d1b3c75ae58ccefc93e72e1 | | MCP tool result | `E_REQUEST_REUSE` | `request_id belongs to another intent` | thegram-format/native/api.rs#a7e13ec4b422ae4907c7d7eac481267103f9b4b86248e706a82251cc597a5e02 | | MCP tool result | `E_REQUEST_ID` | `Nonempty request_id required` | thegram-format/native/api.rs#a7e13ec4b422ae4907c7d7eac481267103f9b4b86248e706a82251cc597a5e02 | | MCP tool result | `E_CAS_REQUIRED` | `base_revision required` | thegram-format/native/api.rs#a7e13ec4b422ae4907c7d7eac481267103f9b4b86248e706a82251cc597a5e02 | | MCP tool result | `E_CAS_REQUIRED` | `Create requires explicit null base_revision` | thegram-format/native/api.rs#a7e13ec4b422ae4907c7d7eac481267103f9b4b86248e706a82251cc597a5e02 | | MCP tool result | `STALE_REVISION` | `Accepted revision or hash changed` | thegram-format/native/temporal.rs#a143cc67c4518c4599f96af9565ae765c1dcdc770d694b13a8fdc08a03c69c0e | | Core import-source CAS | `STALE_REVISION` | `Accepted revision or hash changed; preserve both originals` | thegram-format/native/temporal.rs#a143cc67c4518c4599f96af9565ae765c1dcdc770d694b13a8fdc08a03c69c0e | | MCP tool result | `STALE_REVISION` | `Artifact changed during transaction` | thegram-format/native/store.rs#3bd54253eeee764c2cdf1d3dc1e9c0f4f1d9f96fbd75c66171d96b19a342addc | | MCP tool result | `STALE_REVISION` | `Create target already exists` | thegram-format/native/store.rs#3bd54253eeee764c2cdf1d3dc1e9c0f4f1d9f96fbd75c66171d96b19a342addc | | MCP tool result | `COMMIT_UNKNOWN` | `Replacement published but durability is uncertain: {e}` | thegram-format/native/store.rs#3bd54253eeee764c2cdf1d3dc1e9c0f4f1d9f96fbd75c66171d96b19a342addc | | MCP tool result | `COMMIT_UNKNOWN` | `Marker observed but durability not confirmed: {e}` | thegram-format/native/store.rs#3bd54253eeee764c2cdf1d3dc1e9c0f4f1d9f96fbd75c66171d96b19a342addc | | MCP tool result | `STORAGE_CONFLICT` | `remote file changed since it was read` | thegram-vault/internal/mcp/workspace.go#9de8ccbfe796301fd9406f7b78d775da520dfb77127aea2a3caf499391143ad9 | | MCP tool result | `STORAGE_CONFLICT` | `remote file changed and local restoration failed` | thegram-vault/internal/mcp/workspace.go#9de8ccbfe796301fd9406f7b78d775da520dfb77127aea2a3caf499391143ad9 | | MCP tool result | `E_STORAGE` | `workspace storage is not configured` | thegram-vault/internal/mcp/workspace.go#9de8ccbfe796301fd9406f7b78d775da520dfb77127aea2a3caf499391143ad9 | | MCP tool result | `PROVIDER_AUTH_REQUIRED` | `Google Drive must be reconnected` | thegram-vault/internal/mcp/workspace.go#9de8ccbfe796301fd9406f7b78d775da520dfb77127aea2a3caf499391143ad9 | | MCP tool result | `E_PATH` | `Absolute paths are outside the approved folder` | thegram-vault/internal/mcp/paths.go#754797578ba9858e6db8707f17ca9ceed82914215e83e00e437a05e925bff936 | | MCP tool result | `E_PATH` | `Path does not start with a mounted collection` | thegram-vault/internal/mcp/paths.go#754797578ba9858e6db8707f17ca9ceed82914215e83e00e437a05e925bff936 | | MCP tool result | `E_PATH` | `Path is outside the approved folders` | thegram-vault/internal/mcp/paths.go#754797578ba9858e6db8707f17ca9ceed82914215e83e00e437a05e925bff936 | | MCP tool result | `E_PATH` | `Path is outside an approved folder or hidden` | thegram-vault/internal/mcp/paths.go#754797578ba9858e6db8707f17ca9ceed82914215e83e00e437a05e925bff936 | | MCP tool result | `E_PATH` | `Vault mounts support writes only to top-level documents` | thegram-vault/internal/mcp/paths.go#754797578ba9858e6db8707f17ca9ceed82914215e83e00e437a05e925bff936 | | MCP tool result | `E_READ_ONLY` | `This mounted folder is read-only to agents` | thegram-vault/internal/mcp/paths.go#754797578ba9858e6db8707f17ca9ceed82914215e83e00e437a05e925bff936 | ::end SRC format-language t .gram language specification ref https://github.com/clab-one/thegram-format/blob/main/spec/language.md SRC format-rich t Current rich document specification ref https://github.com/clab-one/thegram-format/blob/main/spec/rich-document.md SRC format-history6 t Current History/6 specification ref https://github.com/clab-one/thegram-format/blob/main/spec/source-history-render.md @gram-history 6 @rev 0 2026-10-12T13:11:21.949Z - 1da291aa94449bf044fae4f97da6dac115885dab1ce7713402adaebe343313dd @rev 1 2026-10-12T13:11:21.949Z portal-reference-contracts agent=developer-doc-generator req=portal-reference-mcp-errors-6915c94fad4acb73e6a3d5f9 dig=e7e1afccb13afb3a kind=SourceImported 74cc999afc678ed8cf15c0a4b4a3468b3d32504b5eac56506a46a52267667e11 @@ 47 1 0 @@ 49 0 2 t .gram language specification @@ 50 1 0 @@ 52 0 1 t Current History/6 specification @rev 2 2026-10-12T13:42:23.507Z portal-reference-finalize agent=developer-doc-generator req=portal-reference-mcp-errors-d3a7f364fb3b232df71328ff dig=7daef26204da88f9 kind=SourceImported 6848269b4ffd9389c5997afec69f72f34ed05589cc94be64f612091b184f912a @@ 4 2 1 ::body @@ 45 19 0 @@ 69 3 0 @rev 3 2026-10-12T13:50:17.490Z portal-reference-finalize agent=developer-doc-generator req=portal-reference-mcp-errors-1e9f76a4b8dffbfd1d5138f3 dig=f7684eb5ffb9fd00 kind=SourceImported 6f4bab64b7a235c3d89fd084fc6f3c542e344e7c48536f95355de0d137abe045 @@ 46 2 0 @@ 59 3 0 @rev 4 2026-10-12T13:53:46.895Z portal-reference-finalize agent=developer-doc-generator req=portal-reference-mcp-errors-ed43bf123593504899e19ff1 dig=bbda4869c7b0e223 kind=SourceImported 05cc97bd69faf7a2bec7de9ff8701661a4267d030e834ff5f7767e381273131b @@ 59 2 0 @rev 5 2026-10-12T23:17:38.121Z portal-reference-finalize agent=developer-doc-generator req=portal-reference-mcp-errors-r4-4624b05a1a91cadd1b02c75b dig=3b7c9192bf53c843 kind=SourceImported a5c8defa526cc5f372939d29111868041613911dfa74462ae4801301d5dc4fc2 @@ 10 1 1 Tool failures are returned as MCP tool results with `isError` and structured `error:{code,message,...details}`; they are not JSON-RPC transport errors. Success commonly includes structured content and text content. There is no official per-tool output JSON Schema: consult each tool's documented source-grounded result contract, and treat optional fields as conditional. The compact response budget is 16,384 bytes. @@ 22 2 2 | `E_REQUEST_REUSE` | Same request ID now refers to another intent. Do not change and retry under that ID; resolve the original receipt and use a new ID for a new intent. | | `COMMIT_UNKNOWN` | Receipt could not establish a commit after an uncertain failure. Retry only the identical patch with the same request ID or check receipt/state; do not claim success. | @@ 36 1 1 3. If outcome is uncertain, check the receipt; otherwise resend exactly the same intent and request ID. @@ 40 1 1 Never reuse an ID for changed operations. The shortened displayed hash maps to a full artifact hash held by the caller's gateway; if a short hash is no longer resolvable, reread rather than guessing. @@ 42 6 0 @@ 54 1 1 ## Exact gateway/Core error messages @@ 56 36 21 | Code | Actual message | Source | |---|---|---| | `STALE_READ` | `The document changed while it was read; read again` | thegram-vault/internal/mcp/tools_common.go | | `STALE_READ` | `The document was replaced while it was read` | thegram-vault/internal/mcp/tools_history.go | | `STALE_CURSOR` | `The documents changed since this cursor; list again` | thegram-vault/internal/mcp/tools_common.go | | `STALE_CURSOR` | `The documents changed since this cursor; ask again without cursor` | thegram-vault/internal/mcp/memory.go | | `STALE_CURSOR` | `Cursor belongs to another document or revision` | thegram-vault/internal/mcp/tools_history.go | | `STALE_CURSOR` | `The cursor belongs to another document, revision or section` | thegram-vault/internal/mcp/memory.go | | `E_REQUEST_REUSE` | `request_id belongs to another intent` | thegram-format/native/api.rs | | `E_CAS_REQUIRED` | `base_revision required` | thegram-format/native/api.rs | | `E_CAS_REQUIRED` | `Create requires explicit null base_revision` | thegram-format/native/api.rs | | `STALE_REVISION` | `Accepted revision or hash changed` | thegram-format/native/temporal.rs | | `STALE_REVISION` | `Accepted revision or hash changed; preserve both originals` | thegram-format/native/temporal.rs | | `STALE_REVISION` | `Artifact changed during transaction` | thegram-format/native/store.rs | | `COMMIT_UNKNOWN` | `Replacement published but durability is uncertain: {underlying error}` | thegram-format/native/store.rs | | `COMMIT_UNKNOWN` | `Marker observed but durability not confirmed: {underlying error}` | thegram-format/native/store.rs | | `STORAGE_CONFLICT` | `remote file changed since it was read` | thegram-vault/internal/mcp/workspace.go | | `STORAGE_CONFLICT` | `remote file changed and local restoration failed` | thegram-vault/internal/mcp/workspace.go | | `E_STORAGE` | `workspace storage is not configured` | thegram-vault/internal/mcp/workspace.go | | `PROVIDER_AUTH_REQUIRED` | `Google Drive must be reconnected` | thegram-vault/internal/mcp/workspace.go | | `E_READ_ONLY` | `This mounted folder is read-only to agents` | thegram-vault/internal/mcp/paths.go |