You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
xAI: undersized images persist in history and prevent session recovery #54325
OpenCode 2.0.25 with xAI Grok 4.7 rejects a tool-result image whose width or height is below 8 pixels. A read of a 6x8 PNG produces:
invalid_image: Image dimensions 6x8 are too small. Both width and height must be at least 8 pixels.
The image is persisted in the session transcript. Further messages include the same image and fail before the model can respond to instructions to resize it. Resizing the original file also leaves the persisted bytes unchanged.
Reproduction:
Use an xAI vision model.
Have the read tool read a 6x8 PNG.
Send another message asking the agent to recover.
Expected: omit incompatible inline media with an explanatory text part, or normalize it before sending, including when replaying saved history. Preserve the source file and transcript.
The request assembly already filters unsupported xAI image formats in packages/core/src/session/model-request.ts, but has no minimum-dimension check. This is distinct from the GIF issue #53786. The same problem applies to JPEG and WebP images with a short side below 8 pixels.
Thanks for the clear report. I could confirm this on 2.0.25 and it still happens on the latest v2 commit (4617210).
There are no xAI credentials here, so I tested the code that builds each request from the saved session history. A real 6x8 PNG returned by the read tool and stored in the history comes out unchanged and is still in the request for provider xai, on every later turn. The current xAI check in packages/core/src/session/model-request.ts only filters by format (so GIFs are handled, as in #53786). Nothing checks image width or height, so xAI's invalid_image ... too small error repeats on every turn, as you describe.
// Reproduction for anomalyco/opencode#54325.// Run from an opencode v2 checkout:// cp xai-small-image.test.ts <repo>/packages/core/test/ && cd <repo>/packages/core && bun test test/xai-small-image.test.ts//// A 6x8 PNG (xAI requires both sides >= 8px) returned by the read tool and stored in the// session history is passed unchanged to the xAI request on every later turn, so xAI// answers each turn with 400 invalid_image and the session cannot recover.import{expect,test}from"bun:test"import{Message,ToolResultPart}from"@opencode/ai"import{boundImages,unsupportedParts}from"@opencode/core/session/model-request"// Real 6x8 RGB PNGconstPNG_6x8="iVBORw0KGgoAAAANSUhEUgAAAAYAAAAICAIAAABVpBlvAAAAEklEQVR4nGP4z8CAhtD5AyIEAGL6L9EoaAtUAAAAAElFTkSuQmCC"test("#54325: undersized image in saved history is still sent to xAI",()=>{consthistory=[Message.user([Message.text("Read tiny.png")]),Message.tool(ToolResultPart.make({id: "call_1",name: "read",result: {type: "content",value: [{type: "text",text: "Image read successfully"},{type: "file",uri: `data:image/png;base64,${PNG_6x8}`,mime: "image/png",name: "tiny.png"},],},}),),Message.user([Message.text("Please recover: resize the image")]),]constcapabilities={tools: true,input: ["text","image"],output: ["text"]}// Same pipeline the request assembly uses: boundImages(unsupportedParts(..., "xai"))constsent=boundImages(unsupportedParts(history,capabilities,"xai"))constresult=sent[1]?.content[0]asanyconstfile=result.result.value.find((item: any)=>item.type==="file")console.log("tool-result parts sent to xAI:",JSON.stringify(result.result.value.map((i: any)=>i.type)))// BUG: the 6x8 image is still included; xAI rejects it with// "invalid_image: Image dimensions 6x8 are too small. Both width and height must be at least 8 pixels."expect(file).toBeDefined()expect(file.uri).toBe(`data:image/png;base64,${PNG_6x8}`)})
Activity
opencode-agent commentedon Oct 10, 2026
Thanks for the clear report. I could confirm this on 2.0.25 and it still happens on the latest
v2commit (4617210).There are no xAI credentials here, so I tested the code that builds each request from the saved session history. A real 6x8 PNG returned by the
readtool and stored in the history comes out unchanged and is still in the request for providerxai, on every later turn. The current xAI check inpackages/core/src/session/model-request.tsonly filters by format (so GIFs are handled, as in #53786). Nothing checks image width or height, so xAI'sinvalid_image ... too smallerror repeats on every turn, as you describe.The script below reproduces it. Related:
Reproduction script (xai-small-image.test.ts)
Run it:
bun xai-small-image.test.ts