vercel/ai · error · UnsupportedFunctionalityError
conflicting descriptions for OpenAI tool namespace "${namesp
Error message
conflicting descriptions for OpenAI tool namespace "${namespace.name}" What it means
prepareResponsesTools groups OpenAI Responses tool definitions that share the same namespace name into a single namespaced tool. The first namespace declaration sets the description; any later declaration of the same namespace name with a different description is treated as contradictory and throws UnsupportedFunctionalityError, because the Responses API only allows one description per namespace.
Source
Thrown at packages/openai/src/responses/openai-responses-prepare-tools.ts:161
});
const namespace = openaiOptions?.namespace;
if (namespace == null) {
openaiTools.push(openaiFunctionTool);
} else {
let namespaceTool = namespaceTools.get(namespace.name);
if (namespaceTool == null) {
namespaceTool = {
type: 'namespace',
name: namespace.name,
description: namespace.description,
tools: [],
};
namespaceTools.set(namespace.name, namespaceTool);
openaiTools.push(namespaceTool);
} else if (namespaceTool.description !== namespace.description) {
throw new UnsupportedFunctionalityError({
functionality: `conflicting descriptions for OpenAI tool namespace "${namespace.name}"`,
});
}
namespaceTool.tools.push(openaiFunctionTool);
}
recordAllowedTool(
tool.name,
namespace != null
? {
supported: false,
reason:
'tools inside an OpenAI tool namespace are not visible to tool_choice.allowed_tools',
}
: openaiOptions?.deferLoading === true
? {
supported: false,View on GitHub (pinned to 69428b1f8b)
Solutions
- Give all declarations of the same namespace name an identical description string
- Use distinct namespace names for tools that need different descriptions
- Consolidate namespace declarations into one shared module/config so there is only a single source of truth
- Drop the conflicting duplicate declaration
Example fix
// before
openai.tools.namespace({ name: 'files', description: 'File ops', tools: [...] })
openai.tools.namespace({ name: 'files', description: 'Document ops', tools: [...] })
// after
openai.tools.namespace({ name: 'files', description: 'File ops', tools: [...] })
openai.tools.namespace({ name: 'documents', description: 'Document ops', tools: [...] }) Defensive patterns
Strategy: validation
Validate before calling
const descriptions = new Map();
for (const ns of namespaceDeclarations) {
if (descriptions.has(ns.name) && descriptions.get(ns.name) !== ns.description) {
throw new Error(`Namespace "${ns.name}" declared with conflicting descriptions`);
}
descriptions.set(ns.name, ns.description);
} Type guard
function hasConsistentNamespaceDescriptions(ns: {name: string; description?: string}[]): boolean {
const seen = new Map<string, string | undefined>();
return ns.every(n => {
const prev = seen.get(n.name);
if (prev !== undefined && n.description !== undefined && prev !== n.description) return false;
seen.set(n.name, n.description);
return true;
});
} Try / catch
try {
await generateText({ model: openai.responses('gpt-4.1'), tools, ... });
} catch (e) {
if (UnsupportedFunctionalityError.isInstance(e) && e.message.includes('conflicting descriptions')) {
// deduplicate namespace declarations or unify descriptions
}
throw e;
} Prevention
- Declare each namespace exactly once in a shared module
- Keep namespace descriptions in a single config constant
- Write a unit test that aggregates all tool declarations and checks namespace consistency
When it happens
Trigger: Passing multiple tools (e.g. via openai.tools.namespace(...)) that share the same namespace.name but supply different namespace.description values to an OpenAI Responses model call (streamText/generateText with openai.responses(...)).
Common situations: Building tool namespaces programmatically or from config where descriptions drift between call sites; merging tool arrays from two modules that both declare the same namespace; copy-pasting a namespace declaration and editing only the description.
Related errors
- allowedTools with only tools that cannot be allow-listed (${
- tool choice type: ${_exhaustiveCheck}
- non-streaming transcription with ${this.modelId}
- streaming transcription with ${this.modelId}
- The ${model.provider} model "${model.modelId}" does not supp
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/aa3968144bd62a2b.
Report an issue: GitHub.