pingdotgg / pingdotgg/t3code

[Bug]: Stopping background work leaves thread stuck in "Monitoring" / "Stopping..." indefinitely

Open
#11,428 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

Description

Metadata & Triage
  • Type: Bug (bug)
  • Area: apps/server, apps/web
  • Estimated Fix Size: size:S (10–29 lines in provider interrupt / task completion cleanup)
  • Impact: Major degradation or frequent failure

Before submitting
  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.
Steps to reproduce
  1. Run a thread where a background command or watch loop (e.g., monitor task, background shell, or log tail) outlives the turn.
  2. Once the assistant turn finishes and settles, the thread shows a Monitoring pill in the sidebar and a • Monitoring banner with a Stop button above the composer.
  3. Click the Stop button on the banner.
Expected behavior

The background tasks should be stopped/interrupted, task.completed or terminal status should be emitted for the running background tasks, the background liveness should clear from the thread, and the Monitoring / Stopping... banner should disappear.

Actual behavior

The button switches to Stopping..., but the thread remains stuck in Monitoring indefinitely. The Stopping... state never clears.

Screenshots

1. Thread showing "Monitoring" badge in sidebar and composer banner with "Stop" button:
Monitoring state

2. Stuck on "Stopping..." indefinitely after clicking Stop:
Stuck on Stopping

Root Cause Analysis
  1. In apps/web/src/components/ChatView.tsx, handleStopBackgroundWork calls interruptThreadTurn under the assumption that it tears down live background work across the thread:
    // Background work (subagent fleets, workflow runs, watch loops) can outlive
    // the turn; once it settles, the composer stop button is gone, so this
    // banner is the only visible stop affordance. Stop routes through the
    // stop-everything interrupt: it kills every live background task before
    // interrupting, and works by session, so no active turn is needed.
    
    isStoppingBackgroundWork holds "Stopping..." until activeBackgroundLiveness === null.
  2. When interruptThreadTurn is called after a turn has settled, turnId is undefined.
  3. In ProviderCommandReactor.ts, the command routes to providerService.interruptTurn({ threadId: event.payload.threadId }).
  4. If the provider adapter's interruptTurn implementation only handles active prompt execution (cancelling active generation / pending approvals) rather than terminating lingering background tasks/commands or emitting terminal task states, ThreadBackgroundLivenessService is never notified that the background task ended.
  5. Because no task.completed or terminal event is received, ThreadBackgroundLivenessService keeps the task in its monitors set.
  6. As a result, activeBackgroundLiveness remains "monitoring", the sidebar badge remains Monitoring, and the composer banner stays stuck in Stopping....

Note on provider implementation: This was observed with the Antigravity provider, where AntigravityAdapter.ts only calls context.runtime.cancel and cancels pending requests inside interruptTurn, but does not clean up context.commands or invoke finishBackgroundCommands(context).

Version or commit

Latest upstream main @ b1e223e2b (v0.0.41-nightly.20260912.1599)

Environment

Desktop / Web app

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in apps/web/src/components/ChatView.tsx at handleStopBackgroundWork, then trace the command through ProviderCommandReactor.ts and the provider interruptTurn implementation, especially AntigravityAdapter.ts. Verify that stopping settled background work produces terminal task state and clears ThreadBackgroundLivenessService so the Monitoring and Stopping... indicators disappear.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend, full-stack
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.