[Bug]: Forking an OpenCode thread right after Stop fails with "Cannot fork OpenCode session ... while it is still working"#24549

opened6d agobyHham-zax

What happened

After I press Stop on a running OpenCode turn and fork the thread, the first message in the fork fails with:

text
1opencode provider protocol error: Cannot fork OpenCode session ses_... while it is still working.

The fork thread itself is created immediately ("Forked from conversation"). The failure appears when its first turn starts, as "Provider turn failed to start".

Reproduction

  1. Open a thread on the OpenCode provider.
  2. Start a turn.
  3. Press Stop.
  4. Fork from an earlier assistant response before T3 processes the interrupted execution's end event.
  5. Send a message in the fork.

This is timing dependent. It is reliable when the source session stays in T3's local active state, for example after a delayed or lost event-stream event.

Expected

Forking a stopped thread starts the fork. A stopped run is no longer writing to the source history.

Actual

The fork's first turn fails with the provider protocol error above.

Root cause

OpenCode2Adapter.forkThread calls ensureQuiet before client.session.fork:

https://github.com/pingdotgg/t3code/blob/main/packages/provider-opencode/src/server/v2/adapter.ts

ensureQuiet treats state.active !== undefined and busy.has(sessionId) as busy without consulting OpenCode. A successful Stop leaves state.active in place until the session.execution.interrupted event arrives. During that window the source is idle at OpenCode, but T3 refuses the fork.

The native fork is deferred until the first turn in the forked thread (ProviderTurnStartService), so the error surfaces as a start failure in the new thread rather than at fork time.

Environment

  • T3 Code 0.1.3-nightly.20261024.3617
  • OpenCode provider (@opencode/client 2.0.28)
  • Linux

Proposed fix

When the local turn is marked interrupted, ask session.active for the authoritative set before refusing. Proceed when OpenCode says the session is idle. Add a regression test for Stop, then fork before the end event arrives.

Synced from GitHub

A focused fix with a regression test is open in #24550.