{"record":{"id":"e12ca238b1c299cb","repo":"vercel/ai","slug":"open-responses-extension-extension-id-cannot-pr-e12ca2","errorCode":null,"errorMessage":"Open Responses extension ${extension.id} cannot provide encodeInputItem without itemTypes and decodeItem.","messagePattern":"Open Responses extension (.+?) cannot provide encodeInputItem without itemTypes and decodeItem\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/open-responses/src/open-responses-extension.ts","lineNumber":221,"sourceCode":"      });\n      registerUnique({\n        map: registry.byToolType,\n        key: toolExtension.toolType,\n        extension: toolExtension,\n        field: 'toolType',\n      });\n    }\n\n    const hasItemTypes = extension.itemTypes != null;\n    const hasItemDecoder = extension.decodeItem != null;\n    if (hasItemTypes !== hasItemDecoder) {\n      throw new Error(\n        `Open Responses extension ${extension.id} must provide itemTypes and decodeItem together.`,\n      );\n    }\n\n    if (extension.encodeInputItem != null && !hasItemDecoder) {\n      throw new Error(\n        `Open Responses extension ${extension.id} cannot provide encodeInputItem without itemTypes and decodeItem.`,\n      );\n    }\n\n    if (hasItemTypes && hasItemDecoder) {\n      const itemExtension = extension as OpenResponsesItemExtension;\n      if (itemExtension.itemTypes.length === 0) {\n        throw new Error(\n          `Open Responses extension ${extension.id} must register at least one item type.`,\n        );\n      }\n      for (const itemType of itemExtension.itemTypes) {\n        assertNamespacedType({\n          extensionId: extension.id,\n          namespace,\n          type: itemType,\n          field: 'itemTypes',\n        });","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/open-responses/src/open-responses-extension.ts#L203-L239","documentation":"encodeInputItem lets an extension encode input items of a custom type, but it requires the decoding side (itemTypes + decodeItem) to exist so the item type is registered and understood. The registry rejects encodeInputItem alone.","triggerScenarios":"Registering an extension with encodeInputItem defined while itemTypes/decodeItem are absent.","commonSituations":"Writing an input-side-only extension assuming the registry will infer types; trimming a full item extension and accidentally keeping encodeInputItem; refactoring that removed the decoder but not the encoder.","solutions":["Add itemTypes and decodeItem to the extension alongside encodeInputItem.","Remove encodeInputItem if the extension should not handle input items.","Define the extension against the OpenResponsesItemExtension interface for compile-time safety."],"exampleFix":"// before\n{ id: 'acme.ticket', encodeInputItem: (item) => ({...}) }\n// after\n{ id: 'acme.ticket', itemTypes: ['ticket'], decodeItem: decodeTicket, encodeInputItem: (item) => ({...}) }","handlingStrategy":"validation","validationCode":"extensions.forEach(e => {\n  const x = e as any;\n  if (x.encodeInputItem != null && (x.itemTypes == null || x.decodeItem == null)) {\n    throw new Error(`${x.id}: encodeInputItem requires itemTypes and decodeItem`);\n  }\n});","typeGuard":"function canEncodeInputItem(e: object): boolean {\n  const x = e as any;\n  return x.encodeInputItem == null || (x.itemTypes != null && x.decodeItem != null);\n}","tryCatchPattern":"try {\n  const registry = createOpenResponsesExtensionRegistry(extensions);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('cannot provide encodeInputItem without itemTypes and decodeItem')) {\n    // add the decoder pair or remove encodeInputItem\n  }\n  throw e;\n}","preventionTips":["Implement encoders and decoders for an item type together, never separately.","Use the OpenResponsesItemExtension interface so TS requires the full set.","Add a registry-construction smoke test per extension.","Keep custom item codecs in one module so halves cannot diverge."],"tags":["open-responses","extension","input-item-encoding","validation"],"backgroundTag":"invalid-extension-configuration","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}