Skip to content

fix(tui): keep mini waiting when session.wait loses its transport - #57062

Merged
thdxr merged 1 commit into
devfrom
fix-waitforidle-timeout
Oct 19, 2026
Merged

thdxr merged 1 commit into
devfrom
fix-waitforidle-timeout

Conversation

@thdxr

@thdxr thdxr commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

Issue for this PR

Closes #50135

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

opencode mini exits with status 1 and ClientError: Transport: The operation timed out. (stack through waitForIdle) when a turn runs longer than Bun's built-in fetch deadline. Latest report: https://x.com/tasarren/status/2112143353017958749 (v2.0.30, mini --standalone).

How it happens:

  • Mini waits for the session to settle with session.wait, a long poll that sends no bytes until the session goes idle.
  • Mini's client uses plain fetch. Bun ends such a request after its default deadline (about 360s on Bun 1.4.2), so the request fails while the session keeps running.
  • In runTurnWait, that error is caught and shown as an error row. But when a prompt was admitted mid-turn (a follow-up typed while busy, or a message from another agent), the queue calls settle → waitForIdle. Nothing catches the error there, so runPromptQueue rejects and the process exits. With --standalone, the private server and the running turn exit along with it.

The fix: settleSession now treats a transport failure of session.wait as the end of that one request, not of the session. It waits for the event stream to be connected again, then calls session.wait again on the current client (which may have been replaced by a reconnect). Aborts and other errors still throw as before. This also stops the bogus "Transport: The operation timed out." row on long turns.

#50248 separately removes Bun's deadline from mini's client (timeout: false, the same as run). The two PRs complement each other: that one avoids the unneeded timeout, and this one keeps mini alive whenever the wait connection drops for any reason (timeout, a reconnect, or a server restart).

How did you verify your code works?

  • New test in packages/tui/test/mini/stream-v2.transport.test.ts: the first session.wait rejects with ClientError("Transport", TimeoutError). waitForIdle waits again and reconciles. It fails on dev and passes with this change (--rerun-each 10).
  • bun test test/mini in packages/tui (414 pass) and bun run check both pass.
  • End to end: mini --standalone from source against a fake OpenAI-compatible provider that holds each completion for 40s, with BUN_CONFIG_HTTP_IDLE_TIMEOUT=2 to shorten Bun's deadline to about 8s. I sent a prompt, then a follow-up while it was busy.
    • On dev: a "Transport: The operation timed out." row appears, then mini exits with status 1 with the same stack as the report (session.wait → waitForIdle → runtime.queue).
    • With this change: a 1m20s turn plus the queued follow-up both finish with no error, and mini stays idle and usable.

Screenshots / recordings

Not a visual change. The before/after was checked in a terminal as described above.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊


Added by the opencode bot (AI-generated).

Related: #54974

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks sound. The new test fails on dev with the same session.wait → waitForIdle Transport error as #50135 and passes with this change. bun test test/mini (414 pass) and typecheck in packages/tui are clean. I tried an end-to-end check with mini --server and BUN_CONFIG_HTTP_IDLE_TIMEOUT=2, but couldn't trigger Bun's deadline on either branch, so that part relies on your manual run.

The retry is narrow: only ClientError with reason Transport while not aborted. Each retry waits for the event stream to reconnect and picks up the current client, so it neither spins nor sticks to a stale client after a reconnect.

Public API is unchanged; the change is internal to mini.

Related: #54974

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mini: session.wait timeout exits with ClientError: Transport after follow-up messages during long-running tasks (v2.0.10)

1 participant