v2: WebSocket idle-timeout bypasses the 3-timeout retry cap, so a dead stream can hold a step for hours
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
Research direction
Read packages/core/src/model-retry.ts, especially the MAX_TIMEOUT_RETRIES policy and the existing HTTP timeout test. Check how the retry reason exposes the WebSocket idle-timeout code, then add it to the timeout cap and cover that case in the policy test. Done means idle-timeout retries stop at the same cap as HTTP timeouts.
Written by the indexing model from the issue text.
Description
Description
A WebSocket stream that goes silent fails with transport code idle-timeout after 30 minutes (packages/core/src/session/model-transport.ts:418-424, IDLE_TIMEOUT = "30 minutes"). The retry policy only counts code === "Timeout" toward MAX_TIMEOUT_RETRIES = 3 (packages/core/src/model-retry.ts:53). So an idle-timeout falls under the general 10-retry allowance, and one dead step can hold a session or subagent for hours.
This shows up after a laptop sleeps or the network drops with agents mid-run. On a v2.0.32 install over one week, 264 model requests failed on transport and took 54.8 request-hours. One review subagent spent 243 of its 256 minutes in 9 failed requests ("Timed out waiting for WebSocket data", "WebSocket closed with code 1006"), each about 15-40 min. The agent also sees these as failed tool calls with empty input (patch {}), so it changes its own behavior instead of recognising a provider stall.
Expected: an idle-timeout counts toward the timeout cap like an HTTP Timeout, the same reasoning as the comment above MAX_TIMEOUT_RETRIES.
Possible fix: in model-retry.ts, count reason.code === "idle-timeout" (WebSocket) along with "Timeout", plus a policy test next to the existing HTTP timeout test.
Plugins
Local plugins only (cache TTL, cost); none touch transport or retry.
OpenCode version
2.0.32 (code references from dev at ce15cd882)
Steps to reproduce
- Start a long task on an OpenAI model over the Responses WebSocket transport.
- Put the machine to sleep, or block network egress, mid-stream for a few minutes, then restore it.
- The step waits 30 min for
idle-timeout, then retries under the general allowance instead of the 3-timeout cap.
Operating System
macOS 27
Terminal
OpenCode TUI
- Dominant language
- TypeScript
- Stars
- 215k
- Forks
- 28.9k
- Avg merge
- 8h 11m
- Merged PRs (30d)
- 365
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from anomalyco/opencode
-
reproduced
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
anomalyco/opencode#57711 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
anomalyco/opencode#57698 · 3 comments ·
Maintainers usually reply within 1 day
-
pending close triaging
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
anomalyco/opencode#57664 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
anomalyco/opencode#57579 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
anomalyco/opencode#57536 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
All issues in anomalyco/opencode
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
paperclipai/paperclip#17151 ·
Maintainers usually reply within 1 day
-
needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
AgoraIO-Extensions/agent-infra#3159 ·
Maintainers usually reply within 1 day
-
blocklist addition
Difficulty 1/5 Under an hour Newbie friendliness 66/100
MetaMask/eth-phishing-detect#304596 ·
Maintainers usually reply within 1 day
-
friction
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
kentcdodds/kody#4142 ·
-
[Bug] Statistics | Task statistics are always empty on MikroORM with MySQL or SQLitePossibly taken @NdekoCode claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
ever-co/ever-gauzy#11214 ·
Maintainers usually reply within 1 day