moeru-ai/airi · error · Error

Unsupported Responses output item

Error message

Unsupported Responses output item: ${item.type}

What it means

readOutput maps each ItemParam in a Responses output array to a projection entry. Known item types (function_call, function_call_output, assistant message) are converted; reasoning, compaction, and web_search_call are intentionally skipped; anything else throws. This is a catch-all for unknown native Responses output item types the portable model cannot represent.

Solutions

  1. Check the item.type value in the failing response; disable or avoid the Responses feature/tool that produced the unsupported item type.
  2. Upgrade core-agent's Responses adapter to a version that skips or maps the new item type.
  3. As a workaround, pre-filter the items array before projection to drop unknown item types.
  4. File an upstream issue to add the item type to the skip list (alongside reasoning/compaction/web_search_call).

Example fix

// before
const items = response.output

// after
const known = ['function_call', 'function_call_output', 'message', 'reasoning', 'compaction', 'web_search_call']
const items = response.output.filter(i => known.includes(i.type))
Defensive patterns

Strategy: try-catch

Validate before calling

const KNOWN_ITEMS = new Set(['function_call', 'function_call_output', 'message', 'reasoning', 'compaction', 'web_search_call'])
const unknown = response.output.filter(i => !KNOWN_ITEMS.has(i.type))
if (unknown.length) console.warn('dropping unsupported output items:', unknown.map(i => i.type))

Type guard

function isProjectableOutputItem(item) {
  return ['function_call', 'function_call_output', 'message', 'reasoning', 'compaction', 'web_search_call'].includes(item?.type)
}

Try / catch

try {
  entries = readOutput(items)
} catch (err) {
  const m = /^Unsupported Responses output item: (.+)$/.exec(err.message)
  if (m) {
    console.error(`Responses item type '${m[1]}' is not supported; disable that feature or upgrade the adapter.`)
  } else throw err
}

Prevention

When it happens

Trigger: generation() -> readOutput() receives an item whose type is not one of function_call, function_call_output, message/assistant, reasoning, compaction, or web_search_call — e.g. 'image_generation_call', 'code_interpreter_call', 'mcp_call', or a typo'd/unknown item type from the Responses API.

Common situations: Enabling new Responses API features (built-in tools that emit their own output item types) on a model whose adapter predates those types; replaying stored continuation data containing item types from a newer API; constructing ItemParam arrays manually with the wrong type string.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of moeru-ai/airi@438a067dde (2026-09-17). Data as JSON: /api/errors/4c4739a24e634c2a. Report an issue: GitHub.

Appendix: source

Thrown at packages/core-agent/src/runtime/responses.ts:148

    if (item.type === 'function_call_output')
      return [{ id, role: 'tool', segments: [{ type: 'tool-result', callId: item.call_id, content: readToolResultContent(item.output) }] }]
    if (item.type === 'message' && item.role === 'assistant') {
      const segments: Extract<ProjectionEntry, { role: 'assistant' }>['segments'] = typeof item.content === 'string'
        ? [{ type: 'text', text: item.content }]
        : item.content.map((part) => {
            if (part.type === 'output_text')
              return { type: 'text', text: part.text, citations: readCitations(part) }
            if (part.type === 'refusal')
              return { type: 'refusal', text: part.refusal }
            throw new Error('Unsupported Responses assistant content')
          })
      return [{ id, role: 'assistant', segments }]
    }
    // These native records have no portable message content. Search citations
    // already belong to the assistant text; opaque state stays in continuation.
    if (item.type === 'reasoning' || item.type === 'compaction' || item.type === 'web_search_call')
      return []
    throw new Error(`Unsupported Responses output item: ${item.type}`)
  })
}

function toolChoice(choice: StreamOptions['toolChoice']): ResponsesOptions['toolChoice'] {
  if (choice == null || typeof choice === 'string')
    return choice
  if (choice.type === 'function')
    return { type: 'function', name: choice.function.name }
  return { type: 'allowed_tools', mode: choice.mode, tools: choice.tools.map(tool => ({ type: 'function', name: tool.function.name })) }
}

/**
 * Projects context directly into Responses and runs stateless tool steps.
 * Only a fully settled generation produces a generated turn for the caller to commit.
 */
export function streamResponses(input: {
  config: ResponsesConfig
  webSearch?: boolean

View on GitHub (pinned to 438a067dde)