{"record":{"id":"5d2354708e82ad89","repo":"JuliusBrussee/caveman","slug":"cave-claude-tool-result-invalid","errorCode":"cave_claude_tool_result_invalid","errorMessage":"cave_claude_tool_result_invalid:${item.name}","messagePattern":"cave_claude_tool_result_invalid:(.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/claude-runtime.ts","lineNumber":169,"sourceCode":"        throw new Error(`cave_claude_tool_schema_unsupported:${item.name}`);\n      }\n      const execute = createHarnessToolExecutor({\n        definition,\n        tool: item,\n        sandbox,\n        ...(options.sandboxProfile === undefined ? {} : { sandboxProfile: options.sandboxProfile }),\n        ...(options.engineBin === undefined ? {} : { engineBin: options.engineBin }),\n      });\n      const wireName = `mcp__caveman_agent__${item.name}`;\n      toolNames.add(wireName);\n      return claudeTool(\n        item.name,\n        item.description,\n        converted.shape,\n        async (args) => {\n          const value = await execute(args, controller.signal);\n          if (!isRecord(value) || !Array.isArray(value.content)) {\n            throw new Error(`cave_claude_tool_result_invalid:${item.name}`);\n          }\n          return value as { content: Array<{ type: \"text\"; text: string }> };\n        },\n        { alwaysLoad: true },\n      );\n    });\n    const mcpServers: NonNullable<ClaudeSDKOptions[\"mcpServers\"]> = {};\n    if (mcpTools.length > 0) {\n      mcpServers.caveman_agent = createSdkMcpServer({\n        name: \"caveman_agent\",\n        version: FRAMEWORK_VERSION,\n        tools: mcpTools,\n        alwaysLoad: true,\n      });\n    }\n    const sdkOptions: ClaudeSDKOptions = {\n      abortController: controller,\n      cwd: rootDir,","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/claude-runtime.ts#L151-L187","documentation":"Tool executors in the Claude bridge must return a record with a content array (an array of { type: \"text\", text: string } blocks). If a tool's execute returns null, a non-record, or a record without an array content field, this error naming the tool is thrown.","triggerScenarios":"A harness tool's execute function returns a bare string, an object lacking a content array, or undefined instead of the { content: [...] } shape.","commonSituations":"Porting tools from another SDK whose result contract differs (e.g. returning plain text); a tool returning its raw domain object instead of wrapping it in content blocks.","solutions":["Return { content: [{ type: \"text\", text: \"...\" }] } from the tool's execute","Wrap existing return values at the end of the executor: return { content: [{ type: \"text\", text: JSON.stringify(value) }] }","Add a runtime check/log at the tool boundary during development to catch malformed results early"],"exampleFix":"// before\nreturn \"done processing file\";\n// after\nreturn { content: [{ type: \"text\", text: \"done processing file\" }] };","handlingStrategy":"type-guard","validationCode":"const result = await toolExecute(args);\nif (!isRecord(result) || !Array.isArray(result.content)) throw new TypeError(`tool ${tool.name} must return { content: [...] }`);","typeGuard":"const isToolResult = (v) => typeof v === \"object\" && v !== null && Array.isArray(v.content) && v.content.every(b => b?.type === \"text\" && typeof b?.text === \"string\");","tryCatchPattern":"try { return await execute(args, signal); } catch (e) { if (String(e.message).startsWith(\"cave_claude_tool_result_invalid:\")) { return { content: [{ type: \"text\", text: String(e) }] }; } throw e; }","preventionTips":["Wrap all tool return values in { content: [{ type: \"text\", text }] }","Add a shared result-shape assertion in your tool harness","Unit-test each tool's executor output shape"],"tags":["tools","contract","claude-runtime"],"backgroundTag":"unexpected-response-shape","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"}