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
fix(core): recover sessions after HTTP 413 payload rejections #53107
V2 classifies a generic HTTP 413 as payload-too-large, but SessionStep only invokes recovery for context-overflow. A session containing inline images can therefore fail on every continuation even with automatic compaction enabled and plenty of token capacity left.
The compaction implementation already supports removing media after a payload rejection; the primary request path never reaches it. Confirmed in 2.0.20 and reproduced by runner tests on current v2 (f72a103a). Expected: compact and rebuild once before any durable output, respecting compaction.auto; keep original history stored.
Plugins
Production: local continuity and compaction-archive plugins. The failing runner regression uses the repository test fixture without those plugins.
OpenCode version
2.0.20 (local build with unrelated TUI fixes); current v2 also reproduces.
Steps to reproduce
Use an OpenAI-compatible gateway with an 8 MiB HTTP body limit and a model with a large token context.
Read enough images for the request body to exceed that limit, while remaining below the default 25 MiB image-history pruning trigger.
Have the gateway return HTTP 413 with {"error":{"code":"proxy_error","message":"Request body exceeds the configured limit."}}.
Continue the session. No recovery compaction occurs; the same history fails again.
Changing only the error code to request_too_large enters token-overflow recovery, exposing the missing handling of the separate payload classification. A fix should retain that distinction and start the recovery summary without inline media.
Screenshot and/or share link
No private session shared. Synthetic runner regression available in the accompanying patch. Related historical report: #36552.
Operating System
macOS, arm64
Terminal
Ghostty; failure is in the session runner, independent of the client.
Additional data point: the oversized-body rejection does not always come from the provider. With the third-party Anthropic auth plugin @ex-machina/opencode-anthropic-auth (<= 2.0.0-next.5), the plugin's own pre-send check throws Anthropic request body exceeds 10485760 byte limit before any HTTP request is made. OpenCode records it as type: "unknown" without a status, so neither the payload-too-large path (#53108) nor the unclassified-4xx path (#56767) applies, and the session dead-ends the same way.
Session: 20 screenshots ≈ 13.7 MB since the last compaction, far below the token limit, so token-based auto-compaction never triggered. A manual compaction recovered it (the compaction request was ~175 KB because media are not sent). The plugin has since raised its limit to 32 MiB (ex-machina-co/opencode-anthropic-auth#282), but errors thrown from request hooks for oversized bodies (or any failure before a response on a request above a few MiB) could also be treated as payload rejections. OpenCode 2.0.32, Windows.
Thanks for the detailed report. I've reproduced this on 2.0.20, and it still happens on the latest dev (c250c272).
What I did: I pointed a mock OpenAI-compatible gateway at OpenCode. It answers any request body over 200 KB with HTTP 413 and {"error":{"code":"proxy_error","message":"Request body exceeds the configured limit."}}. The model has a 1M-token context and compaction.auto is on. I sent one text turn, then a turn with an image of about 480 KB, then a plain --continue.
What happened: the image turn and the next turn both fail with Error: Request body exceeds the configured limit. The gateway only ever receives requests that still contain the image, and no compaction request is sent.
Control: if only the error code changes to request_too_large, OpenCode does send a compaction request without the image. That matches your analysis: the runner in packages/core/src/session/runner/step.ts only starts recovery for context-overflow, not payload-too-large. In that control run, the request rebuilt after compaction still included the image and was rejected again, so that is worth checking in a fix as well.
The script below runs the reproduction. Set ERR_CODE=request_too_large for the control. I couldn't search existing issues, so I haven't checked how #36552 relates.
Reproduction script (run.sh)
#!/usr/bin/env bash# Reproduces #53107: HTTP 413 "payload-too-large" never triggers recovery compaction.# Usage: ERR_CODE=proxy_error|request_too_large ./run.sh (OC="bun ... packages/cli/src/index.ts" to run from source)set -u
cd"$(dirname "$0")"
OC=${OC:-opencode}
PORT=${PORT:-4599}
ERR_CODE=${ERR_CODE:-proxy_error} PORT=$PORT bun mock.ts > mock.log 2>&1&
MOCK=$!; sleep 1; pkill -f "[s]erve --service"; sleep 1
PROJ=$(mktemp -d /tmp/opencode/p413.XXXX); cp big.png "$PROJ/"; mkdir -p "$PROJ"/{home,data,cfg,state,cache};cd"$PROJ"; git init -q
# From source: the CLI respawns itself as `bun src/index.ts serve --service`, which needs the opentui preload.
[ "$OC"!= opencode ] &&echo'preload = ["/workspace/repo/packages/tui/node_modules/@opentui/solid/scripts/preload.js"]'> bunfig.toml
export HOME=$PROJ/home XDG_DATA_HOME=$PROJ/data XDG_CONFIG_HOME=$PROJ/cfg XDG_STATE_HOME=$PROJ/state XDG_CACHE_HOME=$PROJ/cache
export OPENCODE_CONFIG_CONTENT=$(cat <<JSON{"update":"disable","model":"gw/big","compaction":{"auto":true}, "providers":{"gw":{"name":"Gateway","package":"aisdk:@ai-sdk/openai-compatible", "settings":{"apiKey":"k","baseURL":"http://127.0.0.1:$PORT/v1"}, "models":{"big":{"name":"Big","capabilities":{"tools":true,"input":["text","image"],"output":["text"]}, "cost":{"input":0,"output":0},"limit":{"context":1000000,"output":10000}}}}}}JSON)echo"== turn 1 (text)"; timeout 120 $OC run "hello"2>&1| tail -5
echo"== turn 2 (with image, body > 200KB gateway limit)"; timeout 120 $OC run --continue -f big.png "what is in this image"2>&1| tail -8
echo"== turn 3 (continue)"; timeout 120 $OC run --continue "continue"2>&1| tail -8
pkill -f "[s]erve --service";kill$MOCK;echo"== mock log"; cat "$OLDPWD/mock.log"2>/dev/null || cat /workspace/repro/mock.log
Activity
github-actions commentedon Oct 4, 2026
This issue might be a duplicate of existing issues. Please check:
test(session): lock 413 payload rejection as context overflow
olobarius commentedon Oct 18, 2026
Additional data point: the oversized-body rejection does not always come from the provider. With the third-party Anthropic auth plugin
@ex-machina/opencode-anthropic-auth(<= 2.0.0-next.5), the plugin's own pre-send check throwsAnthropic request body exceeds 10485760 byte limitbefore any HTTP request is made. OpenCode records it astype: "unknown"without a status, so neither the payload-too-large path (#53108) nor the unclassified-4xx path (#56767) applies, and the session dead-ends the same way.Session: 20 screenshots ≈ 13.7 MB since the last compaction, far below the token limit, so token-based auto-compaction never triggered. A manual compaction recovered it (the compaction request was ~175 KB because media are not sent). The plugin has since raised its limit to 32 MiB (ex-machina-co/opencode-anthropic-auth#282), but errors thrown from request hooks for oversized bodies (or any failure before a response on a request above a few MiB) could also be treated as payload rejections. OpenCode 2.0.32, Windows.
opencodejr commentedon Oct 27, 2026
Thanks for the detailed report. I've reproduced this on 2.0.20, and it still happens on the latest
dev(c250c272).What I did: I pointed a mock OpenAI-compatible gateway at OpenCode. It answers any request body over 200 KB with HTTP 413 and
{"error":{"code":"proxy_error","message":"Request body exceeds the configured limit."}}. The model has a 1M-token context andcompaction.autois on. I sent one text turn, then a turn with an image of about 480 KB, then a plain--continue.What happened: the image turn and the next turn both fail with
Error: Request body exceeds the configured limit.The gateway only ever receives requests that still contain the image, and no compaction request is sent.Control: if only the error code changes to
request_too_large, OpenCode does send a compaction request without the image. That matches your analysis: the runner inpackages/core/src/session/runner/step.tsonly starts recovery forcontext-overflow, notpayload-too-large. In that control run, the request rebuilt after compaction still included the image and was rejected again, so that is worth checking in a fix as well.The script below runs the reproduction. Set
ERR_CODE=request_too_largefor the control. I couldn't search existing issues, so I haven't checked how #36552 relates.Reproduction script (run.sh)
Run it:
bash run.sh