fix(cli): clear recovered provider errors - #123
Conversation
|
Reviewed and verified — this is the right fix at the right layer, and it's the first of the eight that I'd have written the same way. Merging. Three things worth adding to the record, one of which means the production symptom will not go away when this lands. Root cause confirmed, and the codebase already contains the correct shape
// 507 — proactive: usage came back over the limit
if (!ctx.assistantMessage.summary && isOverflow({ ... })) {
ctx.needsCompaction = true // silent
}
// 641 — reactive: the provider already rejected the request (the 413)
ctx.needsCompaction = true
yield* events.publish(Session.Event.Error, { sessionID: ctx.sessionID, error }) // broadcasts
returnSame recovery, same next step, but one path announces a failure on the error channel and the other doesn't. The CLI then treats every I considered deleting the Verification
The part that isn't finished: cloud still fails the runThis fixes the exit code. The exit code is not what cloud reads. # app.py:2179
if isinstance(event_data, dict) and _event_carries_error(event_data):
seen_error = json.dumps(_extract_event_error(event_data)) # latched, never cleared
...
# app.py:2227
if rc == 0 and not seen_error:
Worth noting the shape sitting immediately above # Finish reason of the most recent LLM call; a truncated call exits rc=0
# with no error event. Overwritten, not accumulated: a run that truncates
# early but finishes cleanly is a success.
last_stop_reason: str | None = NoneThat's exactly the reasoning this PR applies to So the sequencing is: this PR is the precondition, not the fix. Before it, cloud couldn't simply trust I'd want that cloud change reasoned through rather than done reflexively — the question is whether any genuinely-failed run reaches One subtlety to be aware of
I traced it and the outcome is still correct: every fatal continuation re-publishes Also confirmed Upstream
Opening the upstream PR against |
|
Superseding this with #125, which fixes the same bug at the producer. Full reasoning there; the short version of why we changed course after the earlier review approved this: Your diagnosis was correct and your test caught the real regression — both are carried forward into #125 (fixture credited). What changed our mind is that the CLI is one of four consumers of Looking at the producer instead, the publish at That makes every consumer correct as written: your One thing your PR got right that we kept as a hard requirement: the failed-recovery case must still exit 1. That only worked pre-#125 by accident (the halt re-entry during summary published the event), so #125 adds an explicit test pinning exit 1 with exactly one error event when compaction can't shrink the session. The same patch is going upstream to anomalyco/opencode, where this bug exists verbatim — your consumer-side approach remains the right fallback there if they insist on keeping the blip event. Thanks for the report and the fixture; this one was a real production bug with a clean diagnosis. |
Summary
Test plan
bun test test/cli/run/run-process.test.ts --test-name-pattern "exits 0 when compaction recovers a provider size error"bun typecheckfrompackages/opencodeSummary by cubic
Fixes CLI run error recovery so a recovered provider error no longer forces a failure. Non-interactive runs now exit 0 after automatic compaction successfully recovers from a size error.
finishand noerror.Written for commit 066b4b8. Summary will update on new commits.