`run_in_background` Bash call returns "completed" immediately when the script backgrounds its own children, and a follow-up `ps` can miss the still-running children

Status Open
Reported on v2.1.260
Maintainer reply None cached
Activity 0 comments · opened Sep 5, 2026

Summary

When a Bash tool call is issued with run_in_background: true and the command itself spawns detached
children (nohup <cmd> > log 2>&1 &), the harness reports the background task as completed as soon as
the parent shell exits, even though the children keep running. A follow-up Bash call issued right after the
completion notification, checking ps aux | grep <cmd>, showed no matching processes, so the model
concluded the launch had failed and relaunched the same workers. The original children were in fact alive
(a later ps aux showed two processes for the same --worker-id), and both generations wrote to the same
output file concurrently, producing ~1.8x duplicate rows.

Two separable issues:

  1. Completion semantics: "completed" for a run_in_background call means "the shell exited", not

"the work finished". Nothing in the notification distinguishes the two when the command detaches children.

  1. Process visibility right after the notification: the immediate ps check returned nothing for

processes that were demonstrably alive a few seconds later. I could not determine whether this is a timing
artefact of how the harness tears down the background shell's process group or a real visibility issue,
but it is what led to the double launch.

Environment

  • Claude Code 2.1.2xx (observed 2026-08-20; still the same behaviour on 2.1.260), macOS arm64, zsh
  • permissions.defaultMode: "auto"

Minimal reproduction

  1. Call the Bash tool with run_in_background: true and the command

nohup sh -c 'for i in $(seq 1 60); do echo tick $i >> /tmp/bg_probe.log; sleep 1; done' > /dev/null 2>&1 &.

  1. Observe: the background task notification arrives within ~1 s and says the command completed with exit code 0.
  2. Immediately call Bash (foreground) with ps aux | grep -v grep | grep 'seq 1 60'.

In the observed sessions this sometimes printed nothing.

  1. Wait ~5 s and run the same ps again — the process is listed, and /tmp/bg_probe.log keeps growing

for 60 s after the "completed" notification.

Expected

  • Either the completion notification should say that child processes were left running (e.g. by reporting the

number of live descendants at exit), or the docs should state explicitly that run_in_background completion
is shell-exit only and that detaching children inside such a call is unsupported.

  • A ps executed after the notification should reflect the true process state; if there is an intentional

teardown window, documenting it would prevent the "it didn't start" misdiagnosis.

Notes

  • No transcript is attached (it contains unrelated proprietary content); the reproduction above is self-contained.
  • Workaround adopted on our side: never nest nohup … & inside a run_in_background call, and re-check ps

after a few seconds before assuming a background launch failed.

View original on GitHub ↗