Skip to content

needle stop --all reports failure and names PIDs regardless of whether workers actually stopped #21

Description

@brianhendry

Summary

needle stop --all exits non-zero and prints an error naming still-running PIDs whether or not the workers actually stopped. The message, the exit code, and the PIDs it lists are all unreliable — only an external pgrep after a short delay reveals the true state.

Observed nine times over two days on the same machine: three genuine orphans requiring a manual kill, six workers that had already exited by the time pgrep ran five seconds later. The output was indistinguishable in both cases.

Environment

needle 0.6.0
bead-rs 0.2.4
Ubuntu 22.04.5 LTS on WSL2 (Windows 11)
Python 3.10.12, pytest 6.2.5, tmux
Workspace: git repo with a remote, bead-rs backend bound via `needle bead-backend-bind`

Reproduction

needle run --agent claude --identifier alpha
# let it claim and complete a bead
needle stop --all; echo "exit=$?"
sleep 5
pgrep -af "needle run" || echo clean

Actual output (worker had in fact exited)

Error: 1 needle process(es) still running after kill attempt for session 'needle-claude-alpha':
  PID 11469: /home/aperna/.local/bin/needle run --agent claude --count 1 --identifier alpha
no server running on /tmp/tmux-1000/default
Error: needle-claude-alpha - kill attempt reported success but 1 process(es) still running
clean

The tmux session is already gone (no server running), the error names PID 11469, and pgrep five seconds later finds nothing. When the worker genuinely is orphaned, the output is identical.

Worse with multiple workers

With --count 3, each session's stop attempt lists all three PIDs, so the error repeats three times — nine false-alarm lines, zero actual orphans:

Error: 3 needle process(es) still running after kill attempt for session 'needle-claude-alpha':
  PID 12568: ... --identifier alpha
  PID 12611: ... --identifier bravo
  PID 12721: ... --identifier charlie
can't find session: needle-claude-alpha
Error: needle-claude-alpha - kill attempt reported success but 3 process(es) still running
[... repeated for bravo and charlie ...]
clean

The per-session error appears to enumerate the global process list rather than that session's own processes.

Impact

Not merely cosmetic. On 2026-08-30 a worker survived needle stop --all. Because the error looks identical to the harmless case, it was assumed stopped. It continued running after the session ended, completed a bead, wrote a file, and pushed a commit unattended. Work was done that nobody was watching, and nothing in the audit trail indicates the operator believed the system was halted.

For anyone considering unattended or scheduled runs, "did it actually stop" is a question the command currently cannot answer.

Suggested fix

  1. Poll for process exit for a few seconds before deciding the stop failed, so a graceful shutdown in progress is not reported as a failure.
  2. Scope each session's error to that session's own PIDs.
  3. Exit 0 when no processes remain; reserve non-zero for genuine orphans.
  4. If a definitive answer is not possible, say so rather than asserting failure — e.g. "shutdown signalled; verify with pgrep -af 'needle run'".

Current workaround

needle stop --all; sleep 5; pgrep -af "needle run" || echo clean
# only if pgrep itself reports a PID:
kill <that PID>; sleep 5; pgrep -af "needle run" || echo clean

Never kill the PID named in the error — it may already be dead, and the number could have been recycled.

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