{"record":{"id":"aa3968144bd62a2b","repo":"vercel/ai","slug":"conflicting-descriptions-for-openai-tool-namespace","errorCode":null,"errorMessage":"conflicting descriptions for OpenAI tool namespace \"${namespace.name}\"","messagePattern":"conflicting descriptions for OpenAI tool namespace \"(.+?)\"","errorType":"exception","errorClass":"UnsupportedFunctionalityError","httpStatus":null,"severity":"error","filePath":"packages/openai/src/responses/openai-responses-prepare-tools.ts","lineNumber":161,"sourceCode":"        });\n        const namespace = openaiOptions?.namespace;\n\n        if (namespace == null) {\n          openaiTools.push(openaiFunctionTool);\n        } else {\n          let namespaceTool = namespaceTools.get(namespace.name);\n\n          if (namespaceTool == null) {\n            namespaceTool = {\n              type: 'namespace',\n              name: namespace.name,\n              description: namespace.description,\n              tools: [],\n            };\n            namespaceTools.set(namespace.name, namespaceTool);\n            openaiTools.push(namespaceTool);\n          } else if (namespaceTool.description !== namespace.description) {\n            throw new UnsupportedFunctionalityError({\n              functionality: `conflicting descriptions for OpenAI tool namespace \"${namespace.name}\"`,\n            });\n          }\n\n          namespaceTool.tools.push(openaiFunctionTool);\n        }\n\n        recordAllowedTool(\n          tool.name,\n          namespace != null\n            ? {\n                supported: false,\n                reason:\n                  'tools inside an OpenAI tool namespace are not visible to tool_choice.allowed_tools',\n              }\n            : openaiOptions?.deferLoading === true\n              ? {\n                  supported: false,","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/openai/src/responses/openai-responses-prepare-tools.ts#L143-L179","documentation":"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.","triggerScenarios":"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(...)).","commonSituations":"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.","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"],"exampleFix":"// before\nopenai.tools.namespace({ name: 'files', description: 'File ops', tools: [...] })\nopenai.tools.namespace({ name: 'files', description: 'Document ops', tools: [...] })\n// after\nopenai.tools.namespace({ name: 'files', description: 'File ops', tools: [...] })\nopenai.tools.namespace({ name: 'documents', description: 'Document ops', tools: [...] })","handlingStrategy":"validation","validationCode":"const descriptions = new Map();\nfor (const ns of namespaceDeclarations) {\n  if (descriptions.has(ns.name) && descriptions.get(ns.name) !== ns.description) {\n    throw new Error(`Namespace \"${ns.name}\" declared with conflicting descriptions`);\n  }\n  descriptions.set(ns.name, ns.description);\n}","typeGuard":"function hasConsistentNamespaceDescriptions(ns: {name: string; description?: string}[]): boolean {\n  const seen = new Map<string, string | undefined>();\n  return ns.every(n => {\n    const prev = seen.get(n.name);\n    if (prev !== undefined && n.description !== undefined && prev !== n.description) return false;\n    seen.set(n.name, n.description);\n    return true;\n  });\n}","tryCatchPattern":"try {\n  await generateText({ model: openai.responses('gpt-4.1'), tools, ... });\n} catch (e) {\n  if (UnsupportedFunctionalityError.isInstance(e) && e.message.includes('conflicting descriptions')) {\n    // deduplicate namespace declarations or unify descriptions\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["openai","tools","namespaces","unsupported-functionality"],"backgroundTag":"conflicting-tool-namespace-definition","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}