vercel/ai · error · UnsupportedFunctionalityError
allowedTools with only tools that cannot be allow-listed (${
Error message
allowedTools with only tools that cannot be allow-listed (${droppedToolNames.join(', ')}) What it means
When allowedTools is set, prepareResponsesTools filters the tool list down to entries that can actually be allow-listed on the Responses API (e.g. function-type tools). If every entry in allowedTools was dropped because its corresponding tool type cannot be allow-listed, the SDK throws UnsupportedFunctionalityError instead of silently sending an empty allow-list.
Source
Thrown at packages/openai/src/responses/openai-responses-prepare-tools.ts:486
});
continue;
}
if (!resolution.supported) {
toolWarnings.push({
type: 'unsupported',
feature: `allowedTools entry "${name}"`,
details: `${resolution.reason}; the tool is removed from the allowed tools`,
});
droppedToolNames.push(name);
continue;
}
allowedToolEntries.push(resolution.entry);
}
if (allowedToolEntries.length === 0) {
throw new UnsupportedFunctionalityError({
functionality: `allowedTools with only tools that cannot be allow-listed (${droppedToolNames.join(
', ',
)})`,
});
}
return {
tools: openaiTools,
toolChoice: {
type: 'allowed_tools',
mode: allowedTools.mode ?? 'auto',
tools: allowedToolEntries,
},
toolWarnings,
};
}
if (toolChoice == null) {View on GitHub (pinned to 69428b1f8b)
Solutions
- Add at least one allow-listable (function) tool to the tools array and reference it in allowedTools
- Remove non-allow-listable tool names from allowedTools and gate them via toolChoice or application logic instead
- Convert the restricted capability into a custom function tool so it can be allow-listed
Example fix
// before
tools: { web_search: openai.tools.webSearch() },
allowedTools: ['web_search']
// after
tools: { web_search: openai.tools.webSearch(), search_wrapper: tool({...}) },
allowedTools: ['search_wrapper'] Defensive patterns
Strategy: validation
Validate before calling
if (allowedTools.length > 0 && !allowedTools.some(name => name in functionTools)) {
throw new Error('allowedTools must include at least one allow-listable function tool');
} Type guard
function hasAllowListableTool(tools: Record<string, unknown>, allowedTools: string[]): boolean {
return allowedTools.some(name => tools[name] != null);
} Try / catch
try {
await generateText({ model: openai.responses('gpt-4.1'), tools, allowedTools, ... });
} catch (e) {
if (UnsupportedFunctionalityError.isInstance(e) && e.message.includes('cannot be allow-listed')) {
// fall back to calling without allowedTools and enforce restrictions app-side
} else throw e;
} Prevention
- Only put function-tool names in allowedTools
- Keep allowedTools derived from the actual tools object keys
- Remember built-in tools (web_search, etc.) cannot be allow-listed
When it happens
Trigger: Calling an openai.responses(...) model with allowedTools containing only names that resolve to tool types OpenAI cannot allow-list (e.g. web_search, code_interpreter or other built-in/hosted tools) and no allow-listable function tools.
Common situations: Restricting tools in an agent config where the only configured tools are built-in OpenAI tools; renaming a function tool so allowedTools no longer matches an allow-listable entry; copying an allowedTools list from a chat.completions setup to responses.
Related errors
- conflicting descriptions for OpenAI tool namespace "${namesp
- tool choice type: ${_exhaustiveCheck}
- non-streaming transcription with ${this.modelId}
- streaming transcription with ${this.modelId}
- 'text file parts' functionality not supported.
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/9ea1356ff37be5eb.
Report an issue: GitHub.