Skip to content

fix(server): mark restart-recovered turns running after sendTurn - #459

Merged
patroza merged 2 commits into
fork/devfrom
fix/restart-recovery-running-session
Sep 7, 2026
Merged

fix(server): mark restart-recovered turns running after sendTurn#459
patroza merged 2 commits into
fork/devfrom
fix/restart-recovery-running-session

Conversation

@patroza

@patroza patroza commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Problem

After a deploy/restart, reconcileProviderSessions resumes interrupted threads by preparing the orchestration session as starting with activeTurnId: null, then calling sendTurn. It previously left the session in that starting state until the provider emitted turn.started.

Codex resume (thread/resume) often does not emit turn.started until the replacement turn finishes. Meanwhile thread.queue.steer refuses with “still starting a turn”, so queued messages and Send now stay blocked for the whole recovered turn.

This showed up after the #457/#458 upgrade: upstream #10421 made restart resume fire without requiring the directory activeTurnId to match the projection turn, so more in-flight threads recover after a service restart. The stuck-in-starting gap was already in fork recovery; the update just made resume kick in.

Fix

After a successful recovery sendTurn, dispatch thread.session.set with status: "running" and activeTurnId: result.turnId. Prepare still uses starting/null (short window). Failed sendTurn still settles error.

Test

serverRuntimeStartup.reconcile.test.ts now asserts both the prepare starting sets and the post-sendTurn running sets with the admitted turn ids.

After a deploy/restart, continuation prepared the session as starting
with no activeTurnId and waited for turn.started. Codex resume often
never emits that until the replacement turn ends, so queue.steer stayed
blocked for the whole turn. Adopt the sendTurn turn id as running.
@patroza
patroza marked this pull request as ready for review September 7, 2026 07:43
Fork CI Test failed with an unhandled cancelAnimationFrame after
WorkerPoolManager broadcast ran from a leftover setImmediate once
globals were unstubbed. Track and clear those frames the same way
the highlight tests already do.
@patroza
patroza merged commit ecbd38b into fork/dev Sep 7, 2026
8 checks passed
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.

1 participant