Bash tool background command swallows subprocess exit code (reports 0 despite sys.exit(1))
Bug: Background Bash command swallows subprocess exit code
When a subprocess spawned inside a background Bash tool call exits with a non-zero code, the Claude Code harness reports exit code 0 in the completion notification.
Repro steps
- Run a background Bash command that wraps a Python CLI with output redirection:
``bash``
bash -c 'python cli.py reindex --project-root /path/to/project > out.log 2>&1'
cli.pyraises an uncaught exception internally and exits with code 1 (CPython default behavior for uncaught exceptions).- The Claude Code Bash tool notification reports exit code 0.
Expected behavior
Notification exit code should match the actual subprocess exit code (1 in this case).
Actual behavior
Notification always reports exit code 0 for background Bash commands, even when the wrapped process exits non-zero.
Impact
Agents relying on exit-code-based success/failure detection for background commands silently miss failures. The workaround is to emit a strong stderr sentinel (REINDEX FAILED: ...) that log-tail-based harnesses can detect even when the exit code is swallowed.
Workaround
In the subprocess itself, wrap the top-level command body in an explicit try/except Exception and print a distinctive prefix to stderr before returning a non-zero exit code:
def cmd_reindex(args):
try:
return _cmd_reindex_inner(args)
except KeyboardInterrupt:
print("REINDEX FAILED: interrupted", file=sys.stderr, flush=True)
return 130
except Exception as exc:
import traceback
print("REINDEX FAILED: " + repr(exc), file=sys.stderr, flush=True)
traceback.print_exc()
return 1
The REINDEX FAILED: prefix is a text signal any log-tail agent can detect even if the harness swallows the exit code. This defensive pattern was adopted in project-rag v0.5.2 as a workaround.
Environment
- Claude Code Bash tool, background execution mode (
run_in_background: true) - Platform: Windows 11 (PowerShell / bash)
- Subprocess: Python 3.x CLI using
sys.exit(1)
Additional context
Discovered while debugging a background reindex failure in project-rag. The CLI tool's exit code was confirmed correct in isolation; the discrepancy is harness-side.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗