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

  1. Ensure the harness emits the tool-call part before (or atomically with) its approval request, using identical toolCallId values.
  2. Fix any id remapping in the adapter so model tool call ids are forwarded unchanged.
  3. 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

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


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/968e437e6399debf. Report an issue: GitHub.