anthropics / anthropics/claude-code

Bash tool kills every command after ~5s ("output file was replaced or could no longer be verified") when an EDR transiently hard-links new files

Đang mở
#92,586 1 bình luận 0 reaction 0 người được giao Xem trên GitHub
area:bash area:sandbox bug has repro platform:macos
Ngôn ngữ chính
Python
Star
145k
Fork
23.1k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

**Version:** 2.1.263 (also reproduced on 2.1.260). macOS 26.3 (Darwin 25.3.0), Apple Silicon. Genian Insights EDR installed (system extension).

## Symptom

Every Bash tool call, foreground or background, sandboxed or with `dangerouslyDisableSandbox`, dies about 5 seconds after start with exit code 137 and:

```
Command killed: its output file was replaced or could no longer be verified
//tasks/.output could not be read (unknown). This usually means another Claude Code process in the same project deleted it during startup cleanup.>
```

Short commands like `pwd` also fail: the command runs and the output file contains the correct output, but the read-back is reported as failed. No other Claude Code process is active in the project. The Read tool reads the same file fine.

## Root cause

The EDR on this machine adds a second hard link to every newly created file on the boot volume for roughly 1 to 8 seconds, then removes it. `stat` on the task output file shows `nlink=2` during that window, then `nlink=1`. Inode, size, owner, mode and content never change. Claude Code's output-file identity check (introduced in 2.1.251, "a sandboxed command cannot redirect or replace them") treats this state as a replaced file, sends SIGTERM then SIGKILL to the shell, and reports the output as unreadable with error code `unknown`.

## Evidence

- Polling `stat -f %l` on any new file (in /tmp, $HOME, ~/.claude, a 0700 dir) shows nlink 1 → 2 → 1 within ~8s. On a separately mounted APFS RAM disk or sparse image, nlink stays 1.
- A trap inside the shell recorded SIGTERM at exactly +5s from the parent `claude` process; the loop kept writing after that until SIGKILL.
- Headless reproduction with `claude -p "run: echo hi && sleep 7 && echo alive" --allowedTools 'Bash(echo:*)'`:
- default tmp dir: killed, 137
- `CLAUDE_CODE_TMPDIR=~/cctmp` (boot volume, 0700): killed, 137
- `CLAUDE_CODE_TMPDIR=/Volumes//t`: works
- `CLAUDE_CODE_TMPDIR=/Volumes//t`: works

## Expected

A transient extra hard link with unchanged dev/inode is not a replaced file. The check should compare device and inode (and possibly owner/mode) rather than failing on `nlink > 1`, or at least retry before killing the command. The error message blaming "another Claude Code process ... startup cleanup" is misleading here.

## Workaround

Point `CLAUDE_CODE_TMPDIR` at a directory on a separately mounted volume (settings.json `env` works).

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Hướng nghiên cứu

Reproduce with the provided headless claude -p command while polling stat -f %l on the output file, comparing the default boot-volume tmp directory with the APFS RAM disk and sparse image cases. Trace the Bash tool's output-file identity check introduced in 2.1.251 and verify that unchanged device/inode metadata survives a transient extra hard link without killing the command or misreporting the output.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
bash, macos
Lĩnh vực
cli, operating-systems, security
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
55/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.