anthropics / anthropics/claude-code
Monitor/TaskStop removes the task from the panel but leaves the spawned process running (orphaned tail -F accumulates)
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
## Summary
When a `Monitor` task ends — either by hitting its `timeout_ms` or via `TaskStop` — the entry disappears from the tasks panel, but **the process it spawned keeps running**. Re-arming the same monitor every 30 minutes therefore accumulates one orphaned process per cycle, indefinitely.
Same behaviour for background `Bash` tasks: `TaskStop` removes the panel entry without terminating the child process.
## Environment
- Claude Code 2.1.220, desktop app (Code tab)
- Windows 10.0.19045, Git Bash (`Bash` tool)
- Long-running session using `Monitor` to watch a log file
## Reproduce
1. Start a background process that writes to a log (e.g. `Bash` with `run_in_background: true`).
2. Arm a watcher:
`Monitor` → `command: tail -n0 -F /path/to.log | grep --line-buffered -E '^\*\*\*'`, `timeout_ms: 1800000`
3. Wait for the 30-minute timeout (or call `TaskStop`).
4. The task disappears from the panel. Now check the process table:
`ps -ef | grep 'tail -n0 -F'`
5. The `tail` is still running. Re-arm the monitor and repeat — each cycle leaves another one.
## Actual vs expected
- **Actual:** panel entry removed, child process alive and holding the file open. Nothing in the UI indicates it still exists.
- **Expected:** on timeout or `TaskStop`, the spawned process (ideally the whole process group) is terminated.
## Measured impact
In a session that re-arms a log watcher every 30 minutes:
- **10 live `tail -n0 -F ` processes while exactly one Monitor was active** (observed 2026-09-17 08:47).
- Later the same day, **8 more** had accumulated after the session that created them had ended; all 8 confirmed dead only after an explicit `kill` + verification.
- Killed processes were verified with `kill -0` afterwards, because a plain "no output from grep" is not proof of death.
Every leaked `tail -F` keeps a handle on a log file that the session no longer reads, and on Windows they re-parent so they are easy to miss. Because the panel is empty, there is no signal that cleanup is needed — the only way to find them is to inspect the process table manually.
## Workaround
A helper that lists watcher processes (`ps -ef`, not `ps aux` — under Git Bash `ps aux` has no COMMAND column, so `ps aux | grep …` silently returns nothing and looks clean) and prints ready `kill` lines, plus a rule that `TaskStop` is treated as *part* of the kill rather than the cleanup itself:
```
TaskStop AND kill # both, in the same step
```
## Note
This is easy to mistake for correct behaviour, because the missing panel entry reads as "the task is gone". It only becomes visible when something else counts the processes.
Contributor guide
No contributing guide indexed for this repository
Research direction
No repository files or tests are named; start at the Monitor, TaskStop, and background Bash task lifecycle described in the reproduction, then compare timeout and explicit-stop cleanup. Done means stopping either task also terminates its spawned process or process group, including the reproduced Git Bash case, without leaving orphaned processes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bash
- Domain
- cli, operating-systems, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100