{"record":{"id":"e0c8b2742269f917","repo":"moeru-ai/airi","slug":"video-tool-output-is-not-supported-by-the-conversation-model","errorCode":null,"errorMessage":"Video tool output is not supported by the conversation model","messagePattern":"Video tool output is not supported by the conversation model","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core-agent/src/runtime/responses.ts","lineNumber":108,"sourceCode":"}\n\nfunction readToolResultContent(content: Extract<ItemParam, { type: 'function_call_output' }>['output']): InputSegment[] {\n  if (typeof content === 'string')\n    return [{ type: 'text', text: content }]\n  return content.map((part) => {\n    switch (part.type) {\n      case 'input_text': return { type: 'text', text: part.text }\n      case 'input_image':\n        if (!part.image_url)\n          throw new Error('Responses image output requires a URL')\n        return { type: 'image', url: part.image_url, detail: part.detail ?? undefined }\n      case 'input_file':\n        if (part.file_data != null && part.file_url == null)\n          return { type: 'file', data: part.file_data, name: part.filename ?? undefined }\n        if (part.file_url != null && part.file_data == null)\n          return { type: 'file', url: part.file_url, name: part.filename ?? undefined }\n        throw new Error('Responses file requires exactly one source')\n      case 'input_video': throw new Error('Video tool output is not supported by the conversation model')\n    }\n    throw new Error('Unsupported Responses tool output')\n  })\n}\n\ntype AssistantContent = Exclude<Extract<ItemParam, { role: 'assistant' }>['content'], string>[number]\n\nfunction readCitations(part: Extract<AssistantContent, { type: 'output_text' }>): Citation[] | undefined {\n  return part.annotations?.map(entry => ({\n    url: entry.url,\n    title: entry.title,\n    startIndex: entry.start_index,\n    endIndex: entry.end_index,\n  }))\n}\n\nfunction readOutput(items: ItemParam[]): ProjectionEntry[] {\n  return items.flatMap<ProjectionEntry>((item, index) => {","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/moeru-ai/airi/blob/438a067dde47aa0bdb46c2323d1fe293dc805218/packages/core-agent/src/runtime/responses.ts#L90-L126","documentation":"The Responses adapter's readToolResultContent maps function_call_output parts from a stored conversation into portable tool-result segments. When it encounters an 'input_video' part it has no portable representation and throws immediately. Video tool output is intentionally not supported by the conversation model projection, so the adapter fails fast rather than silently dropping the segment.","triggerScenarios":"readOutput() -> readToolResultContent() processes a function_call_output item whose output array contains a part with type 'input_video'. This happens when replaying/re-projecting a conversation that previously recorded a tool result containing video input, or when code constructs a Responses function_call_output with an input_video part.","commonSituations":"A tool (e.g. a media tool) returned video content that was recorded into the Responses continuation data; the same conversation is later re-projected for the next model turn. Also occurs after a library upgrade where a tool began emitting input_video parts that the adapter never handled.","solutions":["Remove or replace the input_video part in the tool result content before it is stored in the conversation (e.g. emit input_text describing the video instead).","Filter out input_video parts when building function_call_output so only input_text/input_image/input_file parts are sent.","If video support is needed, extend readToolResultContent with a portable mapping for input_video and file an upstream issue, since the conversation model currently has no video segment type."],"exampleFix":"// before\nreturn content.map(part => ({ type: part.type, ... }))\n\n// after\nconst supported = content.filter(p => p.type !== 'input_video')\nreturn supported.map(part => ({ type: part.type, ... }))","handlingStrategy":"validation","validationCode":"function hasVideoOutput(output) {\n  return Array.isArray(output) && output.some(p => p && p.type === 'input_video')\n}\nif (hasVideoOutput(segment.content)) throw new Error('strip input_video before recording tool output')","typeGuard":"function isSupportedToolOutputPart(part) {\n  return ['input_text', 'input_image', 'input_file'].includes(part?.type)\n}","tryCatchPattern":"try {\n  const segments = readOutput(items)\n} catch (err) {\n  if (err.message.includes('Video tool output is not supported')) {\n    console.error('Tool emitted video output; convert to text summary before recording.', err)\n  } else throw err\n}","preventionTips":["Never place input_video parts in function_call_output content; represent video results as input_text summaries or input_file references.","Add a whitelist serializer for tool result content before it enters the conversation.","Test tool result replay for every content type your tools can emit."],"tags":["unsupported-media-type","tool-result","responses-api"],"backgroundTag":"unsupported-operation","analyzedSha":"438a067dde47aa0bdb46c2323d1fe293dc805218","analyzedAt":"2026-09-17T01:14:42.644Z","contentChangedAt":"2026-09-17T01:14:42.644Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}