{"record":{"id":"25799b210857b150","repo":"JuliusBrussee/caveman","slug":"cave-tool-result-recovery-mismatch","errorCode":"cave_tool_result_recovery_mismatch","errorMessage":"cave_tool_result_recovery_mismatch","messagePattern":"cave_tool_result_recovery_mismatch","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/agent/src/runtime.ts","lineNumber":3775,"sourceCode":"          details: { effect: definition.effect, resultPolicy: definition.result },\n        };\n      }\n      const mustOffload = definition.result === \"page\" ||\n        definition.result === \"compress\" ||\n        definition.result === \"exact_ccr\" ||\n        raw.byteLength > maxInlineBytes;\n      if (!mustOffload) {\n        return {\n          content: [{ type: \"text\", text: text ?? \"null\" }],\n          details: { effect: definition.effect, resultPolicy: definition.result },\n        };\n      }\n      const transformed = await engineCompress(raw, engineBin);\n      if (!transformed.handle || !recoveryHandles) {\n        throw new Error(\"cave_tool_result_requires_recovery\");\n      }\n      const recovered = await engineRetrieve(transformed.handle, undefined, engineBin);\n      if (!bytesEqual(recovered, raw)) throw new Error(\"cave_tool_result_recovery_mismatch\");\n      recoveryHandles.add(transformed.handle);\n      const compressed = new TextDecoder().decode(transformed.output);\n      return {\n        content: [{\n          type: \"text\",\n          text: [\n            compressed,\n            `<<cave_retrieve:${transformed.handle}>>`,\n            definition.result === \"page\"\n              ? \"Use cave_retrieve with a narrow query to page relevant detail.\"\n              : \"Use cave_retrieve for omitted detail.\",\n          ].join(\"\\n\"),\n        }],\n        details: {\n          effect: definition.effect,\n          resultPolicy: definition.result,\n          recoveryHandle: transformed.handle,\n          recoveryVerified: true,","sourceCodeStart":3757,"sourceCodeEnd":3793,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/runtime.ts#L3757-L3793","documentation":"After offloading a tool result, the runtime reads the payload back with engineRetrieve and byte-compares it with the original. A mismatch means the compress/store/retrieve round trip corrupted the data, so the runtime fails loudly rather than feeding the model altered content.","triggerScenarios":"bytesEqual(engineRetrieve(transformed.handle, undefined, engineBin), raw) returns false after engineCompress at runtime.ts:3775.","commonSituations":"Corrupted engine cache/storage; concurrent invocations overwriting the same handle space; an engine binary bug or version incompatibility; disk corruption in the artifact store.","solutions":["Retry the tool call — a transient storage glitch often resolves on retry.","Verify the engine binary version matches what the runtime expects and reinstall/upgrade it.","Clear the engine's cache/artifact store and rerun.","Check for concurrent invocations sharing one recovery store and isolate per-invocation state."],"exampleFix":"// before: shared engine store across concurrent runs\nconst a = createRuntime({ engineBin, storePath });\nconst b = createRuntime({ engineBin, storePath });\n// after: isolated store per runtime\nconst a = createRuntime({ engineBin, storePath: \"/tmp/store-a\" });\nconst b = createRuntime({ engineBin, storePath: \"/tmp/store-b\" });","handlingStrategy":"retry","validationCode":"// post-hoc self check you can run in your own tool wrapper\nconst round = await engineRetrieve((await engineCompress(payload, engineBin)).handle, undefined, engineBin);\nif (!bytesEqual(round, payload)) console.warn('engine round-trip mismatch detected');","typeGuard":null,"tryCatchPattern":"try {\n  return await callTool(args);\n} catch (e) {\n  if (e?.message === 'cave_tool_result_recovery_mismatch') {\n    await verifyEngineInstall();\n    return retryOnce(() => callTool(args));\n  }\n  throw e;\n}","preventionTips":["Pin and verify the engine binary version the runtime expects.","Give each concurrent runtime its own artifact/recovery store.","Monitor storage health for the artifact cache.","Add a startup integrity self-test for compress/retrieve."],"tags":["data-integrity","recovery","round-trip"],"backgroundTag":"checksum-mismatch","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"}