Repository navigation
Description
What happened
A Claude thread started a Next.js dev server in the background, and the composer showed the bar "Running: Start Next.js dev server" with a Stop button. Clicking Stop makes the button text flicker between "Stop" and "Stopping...", and the bar stays up for a few seconds before it goes away. It flickers again on every click. It looks like Stop didn't work, so I clicked it again.
Diagnosis
On web/desktop, the bar's Stop handler clears its "stopping" state as soon as the server accepts the interrupt command, not when the background task ends:
apps/web/src/components/chat/useThreadLifecycle.tsx:392-404(handleStopBackgroundWork) setsstoppingBackgroundWorkKey, awaitsinterruptThreadTurn, then clears it. The comment there says "Acceptance does not confirm termination. Allow retry while the provider finishes stopping the tasks or reports a failure."useThreadLifecycle.tsx:532-533passes that state asstopDisabled/stopping, andThreadActivityBanners.tsx:155renders"Stopping..."vs"Stop"from it.
The accept round-trip is about 25 ms, but the provider takes about 2 s to stop. So the label shows "Stopping..." for one frame, returns to an enabled "Stop" while the task is still running, and the bar stays until the task is reported ended. Each click repeats this and sends another interrupt.
Server trace for the session (server.trace.ndjson), one burst of clicks:
01:54:56.069 ThreadCommands.interruptTurn 30 ms
01:54:56.099 ProviderTurnControlService.interrupt 2002 ms (ClaudeAdapterV2.interruptTurn 2001 ms)
01:54:57.159 ThreadCommands.interruptTurn 25 ms
01:54:57.627 ThreadCommands.interruptTurn 25 ms
01:54:57.835 ThreadCommands.interruptTurn 21 ms
01:54:58.018 ThreadCommands.interruptTurn 26 ms
01:54:58.109-123 ProviderTurnControlService.interrupt x4, ~0.4 ms each
Five interrupt commands in about 2 s, because the button was re-enabled after each ~25 ms accept while the first ~2 s provider interrupt was still running.
Expected: the button stays "Stopping..." and disabled until the background task leaves the bar or the stop fails. Then it either disappears or re-enables with an error.
References are on main aa247c52. The two web files have no changes to this logic since 2026-10-22.
Steps to reproduce
- In a Claude thread, ask the agent to start a long-running background command, such as
npm run devfor a Next.js app. - After the turn ends, the composer shows "Running: Start Next.js dev server" with Stop.
- Click Stop once. The label flashes "Stopping..." and immediately returns to "Stop" while the bar stays for a few seconds.
- Click Stop again during that window. It flickers again and another interrupt is sent.
Version
T3 Code (Nightly) desktop 0.1.3-nightly.20261024.3630.
Environment
macOS 15.1, desktop app against its local server. Provider: Claude (claudeAgent), model claude-opus-5-5.
Impact
Minor bug. Stop does work eventually, but the UI says it didn't, which invites repeated clicks and sends extra interrupts.
Related
- fix(server): stopping a Claude turn no longer hangs without an acknowledgement #16419 fix(server): stopping a Claude turn no longer hangs without an acknowledgement (server-side stop latency, not this UI state)
- fix(web): keep background tasks visible during follow-up turns #24336 fix(web): keep background tasks visible during follow-up turns (same bar, different problem)
- fix(mobile): confirm before stopping background work from the floating capsule #24385 fix(mobile): confirm before stopping background work from the floating capsule (mobile)
Investigated and drafted by Claude Code (claude-opus-5-5) on the reporter's machine, following .github/triage/PLAYBOOK.md.
Activity
Srijan-D commentedon Oct 25, 2026
Screen.Recording.2026-10-26.at.02.05.27.mov
juliusmarminge commentedon Nov 9, 2026
Fixed by #25002 in 41b3b0b1b6: Stop stays pending while the stopped background tasks remain. Thanks for the detailed report!