[BUG] Persistent Monitor can survive as an orphan (parent dead, child running): the harness stops receiving its events while every liveness check still reports healthy

Status Open
Reported on v2.1.229
Maintainer reply None cached
Activity 0 comments · opened Aug 22, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

A Monitor background task is a shell parent with a child process. Under some conditions the parent dies while the child keeps running. The child keeps polling and keeps writing its state file, but its stdout no longer reaches the harness, so no notification is ever delivered again.

The failure is silent, and it defeats the obvious checks: everything that asks "is it alive" answers yes.

Evidence

On 2026-08-22 09:43 JST we swept all 18 local sessions, pairing each monitor process with its ParentProcessId and testing whether that parent still existed.

18 sessions checked
 5  parent PID no longer exists, child still running   <- orphaned
 1  no monitor at all
12  healthy

One orphan pair had been running since 2026-08-19 08:34:39 - three days - and its start timestamp matched, to the second, the moment that session had run /clear. During those three days that session received no monitor notifications at all, and neither the session nor we noticed.

Why it is hard to detect

The three signals a session would naturally reach for all report healthy:

| signal | what an orphaned monitor reports |
|---|---|
| process present in Win32_Process | present |
| state file mtime still advancing | advancing |
| the session-level self-check tool | OK |

All three ultimately answer the same question - is the process running - and the process is running. None of them answers the question that matters: is the harness still listening to it.

The only external signal we found that distinguishes the two states is whether the parent process still exists. We would not have found it if we had not started enumerating PPIDs for an unrelated reason.

Cost

We reported "monitors are running, everything is fine" twice on the strength of the checks above before discovering the orphans. Five sessions had been silently unreachable - one of them for three days.

What Should Happen?

Either of:

  1. When a monitor's owning shell parent dies, the harness reaps the child - so the failure at least becomes visible as "no monitor", or
  2. expose to the session whether each of its background tasks is still registered with the harness, not merely whether a process exists.

(2) is what we actually need. The distinction we had to reconstruct from PPIDs - "the OS thinks it is running" vs. "the harness is still listening" - is information the harness already has.

Error Messages/Logs

No error is emitted. That is the substance of the report: the orphan looks healthy from every angle the session can see.

Detection is deterministic, though:


$all = Get-CimInstance Win32_Process
$all | Where-Object { $_.CommandLine -like '*<your monitor script>*' } | ForEach-Object {
  $p = $_
  $parent = $all | Where-Object { $_.ProcessId -eq $p.ParentProcessId }
  '{0} PPID={1} parent={2}' -f $p.ProcessId, $p.ParentProcessId, $(if ($parent) { 'alive' } else { 'DEAD' })
}


Any row with `parent=DEAD` whose child is still listed is an orphan. Our sweep output on 2026-08-22 09:43 JST:


18 sessions checked / 5 orphaned / 1 with no monitor / 12 healthy

Steps to Reproduce

We do not have a deterministic repro. What we can say:

  1. Start a Monitor background task with persistent: true.
  2. Leave the session running for hours to days, and run /clear in it at some point (on 2.1.229 this reliably produced the orphan; on 2.1.237 /clear terminates the monitor outright instead - see companion issue #88732).
  3. Enumerate the monitor process and its ParentProcessId.
  4. Observe cases where the parent PID no longer exists while the child is still running and still updating its state file.
  5. Confirm that no notification from that monitor reaches the session, even though every liveness check reports healthy.

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.237 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Environment

  • Claude Code 2.1.229 -> 2.1.237, Windows desktop app (MSIX)
  • OS: Windows 11 Home 10.0.26200
  • Locale: ja-JP
  • About 18 concurrent local sessions on one machine, each with one Monitor background task (persistent: true)

Related

Companion issue: #88732 - on 2.1.237, /clear terminates persistent monitors outright rather than orphaning them. Same practical result (the monitor stops working and nothing says so), different symptom.

Why we are reporting both separately

They need different fixes. #88732 is about notifying the session that its tasks were torn down. This one is about the gap between "the OS process exists" and "the harness is still attached to it" - a state the session currently has no way to observe.

View original on GitHub ↗