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
Run stays "starting" when its thread's recovery state can't be read #16441
When provider-turn.start runs, ProviderTurnStartService reads the thread's runtime recovery state (getRuntimeRecoveryProjection) before it opens a provider session. If that read fails on every attempt, the effect worker gives up and marks the effect failed, but the run stays starting. No error item is written, so the thread shows a turn that never starts and never fails.
Session-open and thread-load failures do not have this problem: on the last attempt they fail the run with an error item (settleStartFailure).
Reproduction
In ProviderTurnStartService.test.ts, make getRuntimeRecoveryProjection fail with a ProjectionStoreReadError and call start({ threadId, runId }) without willRetry (the last attempt). start returns the error and writes nothing; the run is still starting. A real trigger is a stored turn item whose payload no longer decodes: every attempt fails the same way.
Expected
On the last attempt, the run, attempt and root node fail with an error item that names the read failure, as they do for a session-open failure. Earlier attempts keep returning the error so the worker retries.
Note on current design
The existing test "does not commit running state when inherited background routing cannot be read" asserts that nothing is written on this path, and the code comment above loadFromProvider keeps store failures as typed errors. The proposed direction is to treat this one read, which runs before any provider work, like a session-open failure on the last attempt.
Environment
macOS, current main 9bd1d8009a.
A fix with focused tests is ready on a branch: it settles the run on the last attempt and updates the existing test accordingly. I'll open it as a PR if this direction is agreed.
Found while porting fixes from a downstream fork (Scient). Investigated with Claude Opus 5.5 in Claude Code.
Activity