Skip to content

Agents panel (new in #5219): a resumed subagent stays in Earlier and stops updating - 0.0.32-nightly.20260806.1014 #5529

Description

@cristip73

Hey Theo and team,

Context up front: this is about the Agents panel that shipped in #5219 (native subagent & workflow observability). I updated to 0.0.32-nightly.20260806.1014 this afternoon, took the new panel for a spin within the hour, and hit this. So it's a fresh-feature report, not a regression from something older.

Bug first, thank you note at the end - and I mean the second part more than the first.

What happens

When a background subagent finishes and is later resumed (same task id, new run), its row in the Agents panel stays under Earlier, frozen at the first run's duration with its check mark. It never moves back up to Direct spawns, and the elapsed time never changes.

The odd part: the token counter does keep climbing. So the row is clearly still receiving events. Only the run state is stuck.

Repro

  1. Spawn a background subagent from a thread and let it finish.
  2. Send it another message, so the harness resumes it from its transcript.
  3. Watch the Agents panel.

I did this four times on the same agent this afternoon. Roughly nine minutes of work across the four runs. The row still reads 1m 39s, which is exactly the length of run #1.

The data is fine

Checked projection_thread_activities in the local db. All four runs are recorded, in order, on the same task id:

task.started    14:11:04
task.completed  14:12:44
task.started    14:13:09
task.completed  14:15:25
task.started    14:17:52
task.completed  14:21:26
task.started    14:27:39
task.completed  14:27:57

The events arrive. The fold just doesn't act on them.

Likely cause

packages/client-runtime/src/state/subagentRuntime.ts, in the task.started case:

if (agent.activationCount === 0 && !isTerminalSubagentStatus(agent.status)) {
  ...
} else if (agent.status === "idle") {
  applyStatus(agent, "running", at);
}

After the first run the agent is completed, which is terminal but not idle. So the second task.started falls to the else if, fails the idle check, and quietly does nothing.

The comment above it explains the intent, and the intent is sound:

a start row arriving after a terminal state is a late/out-of-order delivery and only fills metadata - it must not reopen the run. Reactivation comes exclusively from explicit status transitions (task.updated / progress status).

The guard was clearly added for a real bug ("a late start reopened a failed child"). The snag is that at this point a genuine resume and a stale duplicate look identical: both are a task.started on a settled agent. And in my case the resume never follows up with a task.progress or task.updated carrying an explicit running, so nothing else picks up the slack.

I deliberately haven't sent a patch, because the right fix depends on what the adapter can be trusted to emit. Something in the payload that separates a fresh run from a replayed row - a run counter, or a start timestamp newer than completedAt - would let the guard stay and still let real resumes through. You'll know which of those is actually safe far better than I would.

Worth saying: this isn't a blocker. Everything works, the reports come back, nothing is lost. It just makes a panel that's genuinely useful look like it has gone to sleep.

Version

0.0.32-nightly.20260806.1014, migration 36. Client and server both on that build - server running headless on a Mac mini, client on macOS. The panel itself is the one from #5219; I have no older build to compare against, since this is the first release where the surface exists.


And the part I actually wanted to write

Thank you. Sincerely.

T3 Code is a dream for me, and I don't use that word loosely. I run a nutrition clinic in Romania, and most of my real thinking happens away from a desk - between patients, in a car, late in the evening. Being able to pick up a Claude session on my phone and keep going has changed how I work more than any tool I've adopted in years.

This very release is a good example of why. Until today I fired off subagents and then simply guessed what they were up to. Now I can watch them. The fact that I found a rough edge within an hour of updating says more about how much I'm using the thing than about the edge.

So please read the above as coming from someone who lives in this app all day and wants it to be even better - not from someone complaining. Thank you for building it, and for shipping at a pace that makes filing a bug feel worth the effort.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions