{"record":{"id":"e8e3ff4909c83e97","repo":"JuliusBrussee/caveman","slug":"caveman-retrieve-failed","errorCode":null,"errorMessage":"caveman_retrieve failed","messagePattern":"caveman_retrieve failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/pi-extension/src/index.ts","lineNumber":154,"sourceCode":"  const GUARD_turn_end = GUARD(\"turn_end\");\n  const GUARD_tool_call = GUARD(\"tool_call\");\n  const GUARD_tool_result = GUARD(\"tool_result\");\n  const GUARD_session_before_compact = GUARD(\"session_before_compact\");\n  const GUARD_session_compact = GUARD(\"session_compact\");\n  const GUARD_session_shutdown = GUARD(\"session_shutdown\");\n\n  pi.registerTool({\n    name: RECOVERY_TOOL,\n    label: \"Retrieve compressed context\",\n    description: \"Recover exact original content from a Caveman recovery handle.\",\n    parameters: Type.Object({\n      recovery_handle: Type.String({ description: \"Exact ccr_ handle returned by Caveman or copied from a <<ccr:HANDLE>> marker.\" }),\n      query: Type.Optional(Type.String({ description: \"One broad description covering every detail needed from this handle.\" })),\n    }),\n    async execute(_toolCallId, params, signal) {\n      const result = await recovery.retrieve(params.recovery_handle, params.query, signal);\n      // MCP errors surface as Pi tool errors (thrown), never as fabricated content.\n      if (result.isError) throw new Error(result.text || \"caveman_retrieve failed\");\n      return { content: [{ type: \"text\", text: result.text }], details: { recovery_handle: params.recovery_handle } };\n    },\n  });\n\n  pi.on(\"session_start\", GUARD_session_start(async (_event: unknown, ctx: ExtensionContext) => {\n    router ??= new ProviderRouter(pi, (message, kind) => notify(ctx, message, kind));\n    // A new/resumed/forked session replaces the runtime; reset everything.\n    gateDone = false;\n    coreContext = undefined;\n    pendingContext = [];\n    pendingBytes = 0;\n    // A failed gate in a replacement session must not retain the old route.\n    if (!(await router.closeGate(ctx))) {\n      gateDone = true;\n      return;\n    }\n    try {\n      sessionId = ctx.sessionManager.getSessionId() || \"default\";","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/pi-extension/src/index.ts#L136-L172","documentation":"In packages/pi-extension/src/index.ts:154, the `caveman_retrieve` Pi tool calls `recovery.retrieve(handle, query, signal)`. If the underlying MCP retrieval returns `isError`, the tool throws an Error whose message is the returned text (or the generic 'caveman_retrieve failed'), so failures surface as real Pi tool errors rather than fabricated content fed back to the model.","triggerScenarios":"Calling the caveman_retrieve Pi tool with an unknown/expired recovery_handle, a bad query, or while the upstream Caveman MCP server returns any error result.","commonSituations":"A model inventing a handle not issued by Caveman; the compressed context expired server-side; MCP server restart or connection loss mid-session.","solutions":["Retry with the exact handle copied from the <<ccr:HANDLE>> marker or the prior tool result.","Check that the Caveman MCP server is running/connected and re-establish the session if needed.","Re-run the original work to mint a fresh handle if the old one is invalid or expired."],"exampleFix":"// before\nawait retrieve({ recovery_handle: 'ccr_guess', query: '...' });\n// after\nawait retrieve({ recovery_handle: 'ccr_abc123', query: '...' }); // handle from the marker\n","handlingStrategy":"try-catch","validationCode":"function assertHandle(handle: string) {\n  if (!/^ccr_/.test(handle)) throw new Error(`Invalid recovery handle format: ${handle}`);\n}","typeGuard":"const isCcrHandle = (h: string): h is `ccr_${string}` => h.startsWith('ccr_');","tryCatchPattern":"try {\n  const result = await recovery.retrieve(handle, query, signal);\n  if (result.isError) throw new Error(result.text || 'caveman_retrieve failed');\n} catch (e) {\n  log(`caveman_retrieve failed for ${handle}: ${String(e)}`);\n  // surface an honest error to the model; do not fabricate content\n  throw e;\n}","preventionTips":["Copy handles verbatim from the tool result or <<ccr:HANDLE>> marker — never invent them.","Treat handles as ephemeral; re-run the original query if retrieval errors persist.","Monitor MCP server connectivity to catch upstream outages early."],"tags":["mcp","tool-error","retrieval","pi-extension"],"backgroundTag":"api-error-response","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}