{"record":{"id":"440942f77c84595f","repo":"vercel/ai","slug":"harness-input-harness-harnessid-could-not-fi","errorCode":null,"errorMessage":"`Harness '${input.harness.harnessId}' could not find parsed tool call '${toolCall.toolCallId}' for custom tool approval.`","messagePattern":"`Harness '(.+?)' could not find parsed tool call '(.+?)' for custom tool approval\\.`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/harness/src/agent/internal/run-prompt.ts","lineNumber":924,"sourceCode":"            };\n          }\n        }\n\n        if (value.type === 'finish') {\n          await waitForOutstandingHostToolExecutions();\n          finalFinish = value;\n          await telemetry.end({\n            finishReason: value.finishReason,\n            usage: value.totalUsage,\n          });\n        }\n\n        // Execute host-side tools when the harness asks for one.\n        if (value.type === 'tool-call' && !value.providerExecuted) {\n          const toolCall = value;\n          const parsedToolCall = toolCallsByToolCallId.get(toolCall.toolCallId);\n          if (parsedToolCall == null) {\n            throw new Error(\n              `Harness '${input.harness.harnessId}' could not find parsed tool call '${toolCall.toolCallId}' for custom tool approval.`,\n            );\n          }\n          if (!hasTool({ tools: activeTools, toolName: toolCall.toolName })) {\n            const output = {\n              type: 'execution-denied',\n              reason: getHarnessV1BuiltinToolFilteringDenialReason({\n                toolName: toolCall.toolName,\n              }),\n            };\n            await control.submitToolResult({\n              toolCallId: toolCall.toolCallId,\n              output,\n            });\n            await telemetry.toolEnd(toolCall.toolCallId, { ok: true, output });\n            continue;\n          }\n          const customToolApprovalDecision = resolveCustomToolApproval({","sourceCodeStart":906,"sourceCodeEnd":942,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness/src/agent/internal/run-prompt.ts#L906-L942","documentation":"The harness emitted a host-side (non-provider-executed) `tool-call` stream part, but the SDK could not find a matching parsed tool call in `toolCallsByToolCallId` when preparing custom tool approval/execution. Every host tool call must have been parsed and registered earlier in the run; a missing entry means the stream is inconsistent, so runPrompt throws.","triggerScenarios":"A stream value with type 'tool-call' and `providerExecuted === false` arrives, and `toolCallsByToolCallId.get(toolCall.toolCallId)` returns null — the tool call was never parsed/registered (parsing failure, id mismatch, or duplicate id reuse).","commonSituations":"Harness adapters that skip or alter the raw tool-call phase; parse errors on earlier tool-call parts silently dropping entries; adapters reusing tool call ids across steps; version drift between harness output schema and SDK parser.","solutions":["Verify the harness adapter emits raw tool calls through the standard stream path so the SDK parses and registers them before host execution.","Check that `toolCallId` values are unique per run and forwarded unchanged from the raw tool call to the parsed tool call.","Update the harness package and SDK to matching versions so stream part schemas agree."],"exampleFix":"// before\nstream.emit({ type: 'tool-call', toolCallId: 'call_2', toolName: 'bash', providerExecuted: false }); // id never parsed\n\n// after\nconst parsed = parseToolCall(rawToolCall);\ntoolCallsByToolCallId.set(parsed.toolCallId, parsed);\nstream.emit(parsed);","handlingStrategy":"validation","validationCode":"if (toolCall.type === 'tool-call' && !toolCall.providerExecuted && !toolCallsByToolCallId.has(toolCall.toolCallId)) {\n  throw new Error(`Unregistered host tool call ${toolCall.toolCallId}`);\n}","typeGuard":"function isRegisteredHostToolCall(part: TextStreamPart, registry: Map<string, unknown>): part is ToolCallTextStreamPart {\n  return part.type === 'tool-call' && !part.providerExecuted && registry.has(part.toolCallId);\n}","tryCatchPattern":"try {\n  await agent.run(...);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('could not find parsed tool call')) {\n    // inspect raw vs parsed tool call ids in the harness stream\n  }\n  throw e;\n}","preventionTips":["Emit raw tool calls through the standard stream so the SDK parses them before host execution.","Keep toolCallId unique per run and stable across raw/parsed stages.","Keep @ai-sdk package versions aligned to avoid schema drift."],"tags":["harness","tool-call","host-tool","id-mismatch"],"backgroundTag":"unknown-tool-call-id","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}