vercel/ai · error

Open Responses extension ${extension.id} must provide itemTy

Error message

Open Responses extension ${extension.id} must provide itemTypes and decodeItem together.

What it means

An Open Responses item extension must pair itemTypes (the item type strings it can decode) with decodeItem (the decoder). Providing one without the other would break round-tripping of items, so the registry throws at construction time.

Source

Thrown at packages/open-responses/src/open-responses-extension.ts:215

      });
      registerUnique({
        map: registry.byProviderToolId,
        key: extension.id,
        extension: toolExtension,
        field: 'provider-tool id',
      });
      registerUnique({
        map: registry.byToolType,
        key: toolExtension.toolType,
        extension: toolExtension,
        field: 'toolType',
      });
    }

    const hasItemTypes = extension.itemTypes != null;
    const hasItemDecoder = extension.decodeItem != null;
    if (hasItemTypes !== hasItemDecoder) {
      throw new Error(
        `Open Responses extension ${extension.id} must provide itemTypes and decodeItem together.`,
      );
    }

    if (extension.encodeInputItem != null && !hasItemDecoder) {
      throw new Error(
        `Open Responses extension ${extension.id} cannot provide encodeInputItem without itemTypes and decodeItem.`,
      );
    }

    if (hasItemTypes && hasItemDecoder) {
      const itemExtension = extension as OpenResponsesItemExtension;
      if (itemExtension.itemTypes.length === 0) {
        throw new Error(
          `Open Responses extension ${extension.id} must register at least one item type.`,
        );
      }
      for (const itemType of itemExtension.itemTypes) {

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Provide itemTypes and decodeItem together as a matched pair.
  2. Remove both if the extension should not handle items.
  3. Annotate the extension as OpenResponsesItemExtension so the type system requires both.

Example fix

// before
{ id: 'acme.ticket', itemTypes: ['ticket'] } // decodeItem missing
// after
{ id: 'acme.ticket', itemTypes: ['ticket'], decodeItem: (item) => ({...}) }
Defensive patterns

Strategy: validation

Validate before calling

extensions.forEach(e => {
  const x = e as any;
  if ((x.itemTypes != null) !== (x.decodeItem != null)) {
    throw new Error(`${x.id}: itemTypes and decodeItem must be provided together`);
  }
});

Type guard

function isCompleteItemExtension(e: object): boolean {
  const x = e as any;
  return (x.itemTypes != null) === (x.decodeItem != null);
}

Try / catch

try {
  const registry = createOpenResponsesExtensionRegistry(extensions);
} catch (e) {
  if (e instanceof Error && e.message.includes('must provide itemTypes and decodeItem together')) {
    // complete the item extension definition
  }
  throw e;
}

Prevention

When it happens

Trigger: Registering an extension that sets itemTypes but not decodeItem, or decodeItem but not itemTypes, in the extensions array of the Open Responses registry.

Common situations: Adding a decoder for a custom item and forgetting to list its type strings; declaring itemTypes while deferring/omitting the decoder implementation; partial object spreads in configuration.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/31c3c7e19a444259. Report an issue: GitHub.