anthropics / anthropics/claude-code

Background Bash task notification reports exit code 0 when the command exited 1

Open
#81,270 0 comments 0 reactions 0 assignees View on GitHub
area:tools
Dominant language
Python
Stars
145k
Forks
23.1k
PR merge metrics
PR metrics pending

Description

# Background task completion notification reports exit code 0 when the command exited 1

**Type:** Harness defect (Claude Code)
**Severity:** High. Silently converts a failing verification run into a passing one.
**Channel:** github.com/anthropics/claude-code/issues
**Reported:** 2026-07-25

## Environment

- Claude Code, model `claude-opus-5[1m]`, reasoning effort `xhigh`
- macOS (darwin 25.5.0), zsh
- Project: ~10k-test JavaScript app, `npm run check:ci` runs eslint + tsc + jest + stylelint + a build

## Summary

A `Bash` tool call launched with `run_in_background: true` completed, and the
resulting `` reported `completed (exit code 0)` when the
underlying command had exited **1**.

Observed **four separate times** in a single session, every time on
`npm run check:ci`.

## Reproduction

Run any long command that exits non-zero via `Bash` with `run_in_background: true`.
To make the true exit code observable independently of the notification, capture it
inside the command:

```bash
npm run check:ci > /tmp/checkci.log 2>&1; echo "CHECKCI_EXIT=$?" >> /tmp/checkci.log
```

## Actual vs expected

**Notification received:**

```

completed
Background command "Run full check:ci in background" completed (exit code 0)

```

**Actual content of the log written by the same command:**

```
CHECKCI_EXIT=1
Test Suites: 4 failed, 256 passed, 260 total
Tests: 48 failed, 4 skipped, 10123 passed, 10175 total
```

Expected: the notification reports exit code 1.

## Impact

The assistant treats the notification as authoritative unless told otherwise. In
this session it only avoided shipping a red build because the project's own stored
notes carried an explicit warning to read a logged exit code rather than trust the
wrapper, so it had instrumented the command by hand.

Without that project-specific workaround, the sequence is: run verification in
background, receive "exit code 0", report the work as verified, commit. The failure
is silent and the reporting reads as confident.

Any user relying on background verification runs is exposed to this.

## Suggested fix

Propagate the real process exit status into the task notification. If the current
value reflects the notification pipeline's own status rather than the child
process's, that distinction needs to be surfaced explicitly rather than presented
as `exit code N`.

## Workaround for other users

Do not trust the exit code in the notification. Capture it inside the command and
read it from the output:

```bash
> log 2>&1; echo "EXIT=$?" >> log
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the Bash tool's run_in_background path and the task-notification pipeline described in the report. Reproduce the command with the provided exit-status capture, then verify that a failing command produces a notification reporting exit code 1 rather than 0.

Written by the indexing model from the issue text.

Assessment

Tech stack
bash, javascript, python
Domain
cli, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.