Skip to content

[Bug]: t3_thread_list reports threads holding awaited background work as completed, so live-status filters skip them #34668

Closed

Description

@nuuls

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. In a Claude thread, have the agent start a long background command (for example sleep 600 with run_in_background), call t3_background_wait on its task id, and end the turn.
  2. The sidebar shows the thread under Working with a "Waiting" pill, as it should.
  3. From another thread, call t3_thread_list with statuses: ["preparing", "queued", "starting", "running", "waiting"], then call it again with no filter.

Expected behavior

Agents and the sidebar agree. The thread appears among the live statuses, or the list item at least says it still holds background work, until that work ends.

Actual behavior

The filtered call does not return the thread at all, and the unfiltered call reports it as status: "completed". Neither t3_thread_list nor t3_thread_read shows pending background work. The only way an agent can find out is t3_thread_wait with untilDelegatedWorkSettled, which blocks on one thread the agent must already suspect.

A coordinating agent or scheduled task that polls the list for live work therefore concludes the work has finished. It may read a result early, message the thread, or clean up its worktree while the background command is still running.

The cause: the list item status and the statuses filter both use only activityRunStatus ?? status. activityRunStatus is null once the turn ends.

Elsewhere this state already counts as busy. Both auto-settle (ThreadSettlementService.ts L157) and the sidebar pill (Sidebar.logic.ts L1243) check backgroundWorkHoldsCompletion(pendingBackgroundTasks). The MCP list is the odd one out.

A possible fix: have the list status and the filter use backgroundWorkHoldsCompletion, either by mapping such threads to waiting or by adding a boolean to the list item. Mapping to waiting overloads the run status of the same name, which means completed work awaiting checkpoints, so a separate field may read more clearly.

Related but different: #28969 (sidebar label for background work), #25306 (empty MCP status filters), #27137 (Cmd+K status filter), and the awaited-task loss and early-settle issues (#28208, #26083, #29899, #30156).

Impact

Minor bug or occasional failure

Version or commit

Seen on a 0.1.9 fork build from 2026-11-10. The same code is on main @ 1e25ef9.

Environment

Linux, desktop app, Claude provider (Opus 5.5)

Logs or stack traces

# t3_thread_list(statuses: [preparing, queued, starting, running, waiting]), while the thread's awaited background command was ~20 min into its run:
{"threads":[<only the calling thread>],"total":1}

# Same thread, unfiltered list:
{"title":"…","status":"completed", …}

# Its provider thread in the projection at the same moment:
pendingBackgroundTasks: [{"kind":"command","awaited":true,"description":"Benchmark …", …}]

Workaround

Open the sidebar and check its Working section, or call t3_thread_wait with untilDelegatedWorkSettled on a thread you already suspect.


Investigated by Opus 5.5 and Fable 5.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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