Skip to content

[Bug]: Status dot stuck on green "Running Tool" while session is actually waiting for approval (no notification) #61

Description

@raphapizzi

What happened?

A Claude Code session that is waiting on an approval prompt (Do you want to proceed? with options 1/2/3) renders with the green pulsing "Running Tool" status dot — both on the tab and in the sidebar — and no attention-bell notification fires. The user has no UI signal that the agent has stopped working and now needs their input.

Expected: the dot should turn into the red attn ("Needs approval") state and the attention bell should surface a waitingForApproval event the moment Claude Code rewrites its pidfile to status: "waiting", waitingFor: "approve <Tool>".

Actual: the dot stays green indefinitely. Switching to the tab and back does not refresh it. Restarting DPlex does correct the status (because the initial scanAll re-reads the pidfile), confirming the on-disk state is correct.

Steps to reproduce

  1. Start a Claude Code session inside DPlex (claude CLI).
  2. Ask the agent to do something that triggers a Bash tool call requiring approval (anything not in the "Yes, don't ask again" list).
  3. Wait for the approval prompt to appear in the terminal.
  4. Observe the tab's status dot and the sidebar — both stay green pulsing.
  5. Observe the attention bell — no badge increment, no notification.

Screenshot

Image

DPlex version

0.15.0 (also reproduces on 0.13.0)

Operating system

macOS

OS version

macOS 15 / Darwin 24.6.0

AI provider involved

Claude Code

Logs or console output

The pidfile on disk has the correct state, but the in-memory registry snapshot is stale:

$ cat ~/.claude/sessions/<pid>.json
{
  "pid": 63996,
  "sessionId": "0d09800d-17fa-43e0-ad79-85c2fb827067",
  "cwd": "/Users/raphaelpizzi/nexus-with-report",
  "status": "waiting",
  "waitingFor": "approve Bash",
  "updatedAt": 1778617553212
}

Root cause analysis

ClaudePidfileRegistry (in src/main/services/providers/claudePidfileRegistry.ts) is purely event-driven — it relies entirely on a single fs.watch() watcher attached to ~/.claude/sessions/ and never polls. On macOS, fs.watch is backed by FSEvents, which is known to coalesce or drop notifications for in-place rewrites of small files — exactly how Claude Code mutates its pidfile when transitioning from status: "busy" to status: "waiting".

When the event is dropped:

  • refreshFile never fires → snapshot stays at status: "busy"
  • mapPidfileStatus keeps returning executingToolStatusDot shows the green pulsing dot
  • attentionService.ingestSessionUpdate never receives the transition into awaitingApproval → no event in the inbox, no notification, badge unchanged

Both symptoms (stuck status dot + missing notification) share this single root cause.

Related but distinct from #59 / #60 (those address AttentionBellButton click-handling once the event is in the inbox; this issue is about the event never landing in the inbox in the first place).

Proposed fix

Add a periodic polling rescan (~2s) as a safety net alongside fs.watch. Polling guarantees eventual consistency when the watcher drops events, while fs.watch continues to provide low-latency updates in the common case.

I've prepared a PR with this fix plus regression tests — incoming.

Before submitting

  • I searched existing issues and this is not a duplicate.
  • I am running the latest released version (or noted the version above).

Activity

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions