vercel/ai · error
Open Responses extension ID ${extension.id} must use <implem
Error message
Open Responses extension ID ${extension.id} must use <implementor>.<extension> format. What it means
Open Responses extensions must be namespaced with an ID of the form '<implementor>.<extension>' so tool/item types cannot collide between implementors. createOpenResponsesExtensionRegistry throws when an extension id lacks a '.' separator (or starts with one), because no namespace can be derived.
Source
Thrown at packages/open-responses/src/open-responses-extension.ts:163
eventTypes: readonly OpenResponsesNamespacedType[];
decodeEvent: NonNullable<OpenResponsesExtension['decodeEvent']>;
};
export function createOpenResponsesExtensionRegistry(
extensions?: readonly OpenResponsesExtension[],
): OpenResponsesExtensionRegistry {
const registry: OpenResponsesExtensionRegistry = {
byEventType: new Map(),
byExtensionId: new Map(),
byItemType: new Map(),
byProviderToolId: new Map(),
byToolType: new Map(),
};
for (const extension of extensions ?? []) {
const namespaceSeparatorIndex = extension.id.indexOf('.');
if (namespaceSeparatorIndex <= 0) {
throw new Error(
`Open Responses extension ID ${extension.id} must use <implementor>.<extension> format.`,
);
}
const namespace = extension.id.slice(0, namespaceSeparatorIndex);
registerUnique({
map: registry.byExtensionId,
key: extension.id,
extension,
field: 'id',
});
const hasToolType = extension.toolType != null;
const hasToolEncoder = extension.encodeTool != null;
if (hasToolType !== hasToolEncoder) {
throw new Error(
`Open Responses extension ${extension.id} must provide toolType and encodeTool together.`,
);View on GitHub (pinned to 69428b1f8b)
Solutions
- Change the id to include a dot: '<implementor>.<extension>' (e.g. 'acme.pdfAnnotation').
- Verify the id contains at least one '.' that is not the first character.
- Ensure the implementor prefix is stable/unique for your organization.
Example fix
// before
const ext = { id: 'pdfannotation', toolType: 'pdf', encodeTool: ... }
// after
const ext = { id: 'acme.pdfannotation', toolType: 'pdf', encodeTool: ... } Defensive patterns
Strategy: validation
Validate before calling
function hasNamespacedId(ext: { id: string }): boolean {
return ext.id.includes('.') && ext.id.indexOf('.') > 0;
}
extensions.forEach(e => { if (!hasNamespacedId(e)) throw new Error(`extension id '${e.id}' must be <implementor>.<extension>`); }); Type guard
function isNamespacedExtensionId(id: string): id is `${string}.${string}` {
return id.indexOf('.') > 0;
} Try / catch
try {
const registry = createOpenResponsesExtensionRegistry(extensions);
} catch (e) {
if (e instanceof Error && e.message.includes('must use <implementor>.<extension> format')) {
// fix the offending extension id before re-creating the registry
}
throw e;
} Prevention
- Always prefix extension ids with your implementor/org name followed by a dot.
- Use a template-literal type `${Org}.${string}` for extension ids.
- Validate extension configs in a shared factory function.
- Keep a registry of existing namespaces to avoid collisions.
When it happens
Trigger: Passing an extension to createOpenResponses / the model constructor with id like 'myext', 'my-ext', or '.hidden' — i.e. indexOf('.') <= 0.
Common situations: Copy-pasting an extension example and renaming the id without keeping the dot; building a custom extension for internal use with a single-word id; typos like 'acme-pdf' intending a dot but using a dash.
Related errors
- Open Responses extension ${extension.id} must provide toolTy
- Open Responses extension ${extension.id} cannot provide enco
- Open Responses extension ${extension.id} must provide itemTy
- Open Responses extension ${extension.id} cannot provide enco
- maxEmbeddingsPerCall must be greater than 0
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/26768662a9bfef2a.
Report an issue: GitHub.