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
[Bug] A chat past the provider's image cap can never be recovered: no pruning, and "Try again" re-sends the same history #1289
Environment: ThinkRail 0.3.2 (stable, ~/.local/bin/thinkrail.exe), Windows 11, provider enforces a per-conversation image cap (the 400 below is Anthropic-shaped: invalid_request_error, "we currently limit the number of images per conversation to 120").
Symptom: once a chat has accumulated more image blocks than the provider allows, every subsequent turn fails, including plain text turns and including the UI's own "Try again", which re-sends the same history:
400: {"message":"Too many images were provided, we currently limit the number of images per conversation to 120 (ref: …)","type":"invalid_request_error","param":null,"code":null}
There is no way back from inside the app: the composer stays enabled, the retry button is offered, and each attempt reposts the oversized history. The only recovery is editing the transcript on disk by hand.
How the chat got there: image blocks are stored inline in the transcript, {type:'image', data:'<base64>', mimeType:'image/png'}, inside message/toolResult content arrays. Screenshots that a tool returns (Playwright/MCP page.screenshot, or a pasted clipboard image) are kept forever. The affected transcript here:
entries
3 010
image blocks
182 across 165 entries
base64 payload
27.3 MB (file 33.4 MB)
compactions already in the file
3
provider limit
120
Compaction does not remove image blocks, so it doesn't bring the chat back under the cap.
Expected: a conversation should stay usable no matter how many images have passed through it — the same principle that already applies to context compaction. At minimum the failure should be actionable (say the chat is over the provider's image cap and what to do) instead of offering a retry that cannot succeed.
Suggested approach: prune at send time rather than in the UI. Build the request with at most N recent image blocks (N configurable, comfortably under the smallest provider limit) and replace older ones with a short text placeholder, the way long tool output is already elided. Doing it while compacting would also keep transcripts small (this one is 33 MB, 27 MB of it images). Both paths are cheap compared with the current dead end.
Workaround used to recover the chat: copy the .jsonl aside, walk the entries and replace every {type:'image',…} block outside the most recent 20 entries with a text placeholder, keep everything else identical. 3 010 entries and all text preserved, images 182 → 20, file 33.4 MB → 9.3 MB, and the chat sends again.
Related:#671 (WebSocket frames over 16 MB close the socket while the composer allows 24 MB of images) is a different failure on the same unbounded-image path — one is the transport, this is the provider cap. Fixing the send-time pruning would make #671 much harder to reach.
Activity