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
- Check the item.type value in the failing response; disable or avoid the Responses feature/tool that produced the unsupported item type.
- Upgrade core-agent's Responses adapter to a version that skips or maps the new item type.
- As a workaround, pre-filter the items array before projection to drop unknown item types.
- 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
- Only enable Responses built-in tools whose output item types the adapter supports.
- Wrap readOutput in a filter that drops unknown item types when forward compatibility matters.
- Update the skip list whenever the upstream API adds item types you intend to use.
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
- Unsupported Responses assistant content
- Unsupported Responses tool output
- Only assistant messages can invoke tools
- Responses continuation must contain an item array
- Responses file requires exactly one source
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?: booleanView on GitHub (pinned to 438a067dde)