vercel/ai · error · UIMessageStreamError
No tool invocation found for approval ID "${approvalId}".
Error message
No tool invocation found for approval ID "${approvalId}". What it means
In process-ui-message-stream.ts, a 'tool-approval-response' chunk carries an approvalId; getToolInvocationByApprovalId searches the message's tool invocations for one whose `approval.id` matches. If no tool invocation has that approval ID, a UIMessageStreamError is thrown. The approval response references an approval request that does not exist in current message state.
Source
Thrown at packages/ai/src/ui/process-ui-message-stream.ts:167
throw new UIMessageStreamError({
chunkType: 'tool-invocation',
chunkId: toolCallId,
message: `No tool invocation found for tool call ID "${toolCallId}".`,
});
}
return toolInvocation;
}
function getToolInvocationByApprovalId(approvalId: string) {
const toolInvocations = state.message.parts.filter(isToolUIPart);
const toolInvocation = toolInvocations.find(
invocation => invocation.approval?.id === approvalId,
);
if (toolInvocation == null) {
throw new UIMessageStreamError({
chunkType: 'tool-approval-response',
chunkId: approvalId,
message: `No tool invocation found for approval ID "${approvalId}".`,
});
}
return toolInvocation;
}
function updateToolPart(
options: {
toolName: keyof InferUIMessageTools<UI_MESSAGE> & string;
toolCallId: string;
providerExecuted?: boolean;
title?: string;
toolMetadata?: JSONObject;
} & (
| {View on GitHub (pinned to 69428b1f8b)
Solutions
- Ensure the tool invocation with `approval.id === approvalId` exists in the target message before emitting the approval response (keep messages containing the approval request).
- Use the approval object returned by the tool-approval-request chunk directly instead of manually constructed IDs.
- Check that approval responses target the correct message and are not split across conversations.
- Catch UIMessageStreamError for tool-approval-response chunks and surface a user-friendly 'approval no longer valid' state.
Example fix
// before
transport.sendMessages({ chatId, messages, trigger: 'tool-approval-response', ... }) // stale approvalId
// after
const approval = message.parts.find(p => p.type === 'tool-approval-request')?.approval;
// use approval.id from the live message part to build the response Defensive patterns
Strategy: validation
Validate before calling
const target = messages
.flatMap(m => m.parts)
.find(p => p.type === 'tool' && p.approval?.id === approvalId);
if (!target) throw new Error(`No pending approval with id ${approvalId}`); Type guard
function hasApproval(msg: UIMessage, approvalId: string): boolean {
return msg.parts.some(p => p.type === 'tool' && p.approval?.id === approvalId);
} Try / catch
try {
await sendToolApprovalResponse({ approvalId, approved });
} catch (e) {
if (e instanceof Error && /No tool invocation found for approval ID/.test(e.message)) {
setApprovalState('expired'); // show 'approval no longer valid' UI
} else throw e;
} Prevention
- Build approval responses from the approval object in the live message part, never hardcoded IDs.
- Keep messages containing pending approval requests in state until resolved.
- Disable approve/reject UI once the message list resets or the approval is consumed.
- Clear stale approval IDs after reconnects or message trimming.
When it happens
Trigger: Sending/processing a tool-approval-response chunk whose approvalId has no matching tool invocation (no prior tool-approval-request chunk, or the invocation was in a different message), e.g. when addToolApprovalResponse is called with a stale or wrong approval ID.
Common situations: Approving after the message list was trimmed/reset so the approval request no longer exists; copy-pasted or hardcoded approval IDs; multiple approval requests where the user's UI passed the wrong one; reconnect/replay dropping the approval-request chunk.
Related errors
- Tool call "${toolCallId}" not found for approval request "${
- No tool invocation found for tool call ID "${toolCallId}".
- Could not find tool approval request ${request.approvalId}.
- 'element streams in no-schema mode' functionality not suppor
- 'element streams in object mode' functionality not supported
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/e239b553bb9cd73a.
Report an issue: GitHub.