vercel/ai · error

`Harness '${input.harness.harnessId}' emitted approval reque

Error message

`Harness '${input.harness.harnessId}' emitted approval request '${displayValue.approvalId}' for unknown tool call '${displayValue.toolCallId}'.`

What it means

The harness emitted a `tool-approval-request` display value whose `toolCallId` does not match any tool call the SDK has parsed and tracked for the current run. The SDK keeps a lookup (`toolCallsByToolCallId`) of parsed tool calls and validates every approval request against it; an approval for an unknown tool call is a harness protocol violation, so runPrompt throws.

Source

Thrown at packages/harness/src/agent/internal/run-prompt.ts:726

          (displayValue.type === 'tool-call' ||
            displayValue.type === 'tool-approval-request') &&
          settledBuiltinApprovalToolCallIds.has(displayValue.toolCallId);

        if (settledHostInputReplay || settledBuiltinApprovalReplay) {
          continue;
        }

        if (displayValue.type === 'finish-step' && closingResumedStep) {
          closingResumedStep = false;
          resetStepContent();
          result.discardCurrentStepContent();
          continue;
        }

        if (displayValue.type === 'tool-approval-request') {
          const toolCall = toolCallsByToolCallId.get(displayValue.toolCallId);
          if (toolCall == null) {
            throw new Error(
              `Harness '${input.harness.harnessId}' emitted approval request '${displayValue.approvalId}' for unknown tool call '${displayValue.toolCallId}'.`,
            );
          }
          const rawToolCall = rawToolCallsByToolCallId.get(
            displayValue.toolCallId,
          );
          const toolName = rawToolCall?.toolName ?? toolCall.toolName;
          if (
            !isHarnessV1BuiltinToolIncluded({
              toolName,
              toolFiltering: input.builtinToolFiltering,
            })
          ) {
            if (control.submitToolApproval == null) {
              throw new Error(
                `Harness '${input.harness.harnessId}' emitted a built-in tool approval request but does not support approval responses.`,
              );
            }

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Fix the harness adapter so approval requests always reference the `toolCallId` of a tool call emitted in the same run's stream.
  2. Check for duplicate/replayed approval events in the adapter (e.g. resuming a session re-emits old approval requests) and filter them.
  3. Ensure the harness forwards the model's tool call ids verbatim rather than remapping them.

Example fix

// before
harness.emit({ type: 'tool-approval-request', approvalId, toolCallId: internalId });

// after
harness.emit({ type: 'tool-approval-request', approvalId, toolCallId: modelToolCall.id });
Defensive patterns

Strategy: validation

Validate before calling

const knownIds = new Set(streamToolCalls.map(c => c.toolCallId));
for (const req of approvalRequests) {
  if (!knownIds.has(req.toolCallId)) {
    throw new Error(`Approval ${req.approvalId} references unknown toolCallId ${req.toolCallId}`);
  }
}

Try / catch

try {
  await agent.run(...);
} catch (e) {
  if (e instanceof Error && /emitted approval request .* for unknown tool call/.test(e.message)) {
    // log harness stream for debugging; fix adapter id mapping
  }
  throw e;
}

Prevention

When it happens

Trigger: During runPrompt stream processing, a display value of type 'tool-approval-request' arrives and `toolCallsByToolCallId.get(displayValue.toolCallId)` returns null — the harness references a tool call id it never emitted, already consumed, or fabricated.

Common situations: Harness adapters that generate approval requests from their own internal ids instead of the stream's tool call ids; adapters replaying stale approval requests after a resume/retry; id-mapping bugs where harness-side ids differ from LanguageModelV* tool call ids.

Related errors


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