Summary
After a Claude Agent turn completed normally, the thread's composer send button stayed disabled. The thread projection shows the turn as completed and the session as ready, but the persisted provider runtime still records the finished turn as active.
Version / environment
- T3 Code
0.0.43-nightly.20260929.2428 (Electron, Windows 10 Pro 19045)
- Provider:
claudeAgent, model claude-sonnet-5 (effort medium, context 200k), runtime mode full-access
- Thread in a T3 worktree; 3 turns, all completed without error
What happened
- Sent the 3rd message in the thread (turn
c7d3b361…, sent 13:01:18Z).
- The turn streamed and finished normally; the provider log shows
result (subtype: success, stopReason: end_turn), then turn.completed (13:02:14.353Z), then command_lifecycle: completed.
- The send button then stayed disabled. There were no pending approvals, user-input requests or actionable plans (all counts 0), and no
lastError.
Persisted state afterwards (state.sqlite)
| Table |
State |
projection_turns (turn c7d3b361…) |
state: completed, completed_at: 13:02:14.349Z, checkpoint ready |
projection_thread_sessions |
status: ready, active_turn_id: null, last_error: null |
projection_threads |
latest_turn_id: c7d3b361…, pending_approval_count: 0, pending_user_input_count: 0 |
provider_session_runtime |
status: running, runtime_payload_json.activeTurnId: "c7d3b361…", lastRuntimeEvent: "provider.sendTurn", lastRuntimeEventAt: 13:01:18.719Z, last_seen_at: 13:02:14.351Z |
last_seen_at was updated at completion time, but activeTurnId and lastRuntimeEvent still hold the values from when the turn was sent. It looks like the runtime payload isn't updated on turn.completed, or a later write overwrites it with a stale copy.
Of the 27 threads with a runtime row, this was the only one where the projection said ready and the runtime still had an activeTurnId. The other rows were either stopped with no active turn, or running with a turn that really was in progress.
Expected
On turn.completed, clear activeTurnId in the persisted runtime payload (and in any in-memory copy) so the thread accepts new messages.
Workaround
With T3 Code running, I set runtime_payload_json.activeTurnId to null for that thread, after backing up the database. The in-memory server state is presumably still stale, so restarting the app is probably also needed. I didn't want to restart because another thread had a turn in progress.
Possibly related
Summary
After a Claude Agent turn completed normally, the thread's composer send button stayed disabled. The thread projection shows the turn as completed and the session as
ready, but the persisted provider runtime still records the finished turn as active.Version / environment
0.0.43-nightly.20260929.2428(Electron, Windows 10 Pro 19045)claudeAgent, modelclaude-sonnet-5(effortmedium, context200k), runtime modefull-accessWhat happened
c7d3b361…, sent 13:01:18Z).result(subtype: success,stopReason: end_turn), thenturn.completed(13:02:14.353Z), thencommand_lifecycle: completed.lastError.Persisted state afterwards (
state.sqlite)projection_turns(turnc7d3b361…)state: completed,completed_at: 13:02:14.349Z, checkpointreadyprojection_thread_sessionsstatus: ready,active_turn_id: null,last_error: nullprojection_threadslatest_turn_id: c7d3b361…,pending_approval_count: 0,pending_user_input_count: 0provider_session_runtimestatus: running,runtime_payload_json.activeTurnId: "c7d3b361…",lastRuntimeEvent: "provider.sendTurn",lastRuntimeEventAt: 13:01:18.719Z,last_seen_at: 13:02:14.351Zlast_seen_atwas updated at completion time, butactiveTurnIdandlastRuntimeEventstill hold the values from when the turn was sent. It looks like the runtime payload isn't updated onturn.completed, or a later write overwrites it with a stale copy.Of the 27 threads with a runtime row, this was the only one where the projection said
readyand the runtime still had anactiveTurnId. The other rows were eitherstoppedwith no active turn, orrunningwith a turn that really was in progress.Expected
On
turn.completed, clearactiveTurnIdin the persisted runtime payload (and in any in-memory copy) so the thread accepts new messages.Workaround
With T3 Code running, I set
runtime_payload_json.activeTurnIdtonullfor that thread, after backing up the database. The in-memory server state is presumably still stale, so restarting the app is probably also needed. I didn't want to restart because another thread had a turn in progress.Possibly related
running)