vercel/ai · error
`Harness '${input.harness.harnessId}' emitted approval reque
Error message
`Harness '${input.harness.harnessId}' emitted approval request '${value.approvalId}' for unknown tool call '${value.toolCallId}'.` What it means
Same family as the 'unknown tool call' error: the harness emitted a `tool-approval-request` whose `toolCallId` is absent from the SDK's parsed-tool-call registry. runPrompt validates every approval request against `toolCallsByToolCallId` and throws when the referenced tool call was never parsed in this run, because the approval cannot be correlated with an actual tool invocation.
Source
Thrown at packages/harness/src/agent/internal/run-prompt.ts:843
toolName: value.toolName,
input: value.input,
});
}
// Telemetry: close a tool span when its provider-executed result lands.
if (value.type === 'tool-result') {
await telemetry.toolEnd(
value.toolCallId,
value.isError
? { ok: false, error: value.result }
: { ok: true, output: value.result },
);
}
if (value.type === 'tool-approval-request') {
const toolCall = toolCallsByToolCallId.get(value.toolCallId);
if (toolCall == null) {
throw new Error(
`Harness '${input.harness.harnessId}' emitted approval request '${value.approvalId}' for unknown tool call '${value.toolCallId}'.`,
);
}
const rawToolCall = rawToolCallsByToolCallId.get(value.toolCallId);
const pendingApproval =
pendingApprovalsByApprovalId.get(value.approvalId) ??
({
approvalId: value.approvalId,
toolCallId: value.toolCallId,
toolName: toolCall.toolName,
input: rawToolCall?.input ?? JSON.stringify(toolCall.input),
kind: 'builtin',
providerExecuted: rawToolCall?.providerExecuted ?? true,
...(rawToolCall?.nativeName !== undefined
? { nativeName: rawToolCall.nativeName }
: {}),
} satisfies HarnessV1PendingToolApproval);View on GitHub (pinned to 69428b1f8b)
Solutions
- Ensure the harness emits the tool-call part before (or atomically with) its approval request, using identical toolCallId values.
- Fix any id remapping in the adapter so model tool call ids are forwarded unchanged.
- Suppress/dedupe replayed approval events when resuming a harness session.
Example fix
// before const pending = harness.createApproval(toolCall.internalKey); // remapped id // after const pending = harness.createApproval(toolCall.toolCallId); // id as streamed
Defensive patterns
Strategy: validation
Validate before calling
const tracked = new Set(parsedToolCalls.map(c => c.toolCallId));
if (!tracked.has(approvalRequest.toolCallId)) {
throw new Error(`Harness emitted approval for untracked tool call ${approvalRequest.toolCallId}`);
} Try / catch
try {
await agent.run(...);
} catch (e) {
if (e instanceof Error && /for unknown tool call/.test(e.message)) {
// capture harness stream, fix adapter id forwarding
}
throw e;
} Prevention
- Create approval requests only from parsed tool call objects.
- Do not remap or regenerate tool call ids inside the adapter.
- Cover approval flows in adapter integration tests.
When it happens
Trigger: A stream value of type 'tool-approval-request' is processed and `toolCallsByToolCallId.get(value.toolCallId)` is null — the harness references a tool call id not present in the current run's stream.
Common situations: Adapter id-remapping bugs; approvals emitted before the corresponding tool-call part is streamed; stale approvals replayed after resumption; harnesses that fabricate ids for internally-initiated tool calls.
Related errors
- `Harness '${input.harness.harnessId}' emitted approval reque
- `Harness '${input.harness.harnessId}' could not find parsed
- `Harness session ${this.sessionId} has an unfinished turn an
- `Harness '${input.harness.harnessId}' emitted a built-in too
- `Harness '${input.harness.harnessId}' could not find parsed
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/968e437e6399debf.
Report an issue: GitHub.