# task-888.1 완료 보고서: Exit code 144 / Sibling tool call errored 조사

**팀**: dev1-team (헤르메스)
**레벨**: Lv.1 (리서치/조사)
**일시**: 2026-03-24

---

## SCQA

**S**: 우리 시스템(아누 세션)에서 병렬 Bash tool call 실행 시 `Exit code 144` + `Sibling tool call errored` 에러가 빈번하게 발생하고 있다. DIRECT-WORKFLOW.md에 5개 안전 규칙을 이미 적용 중이다.

**C**: 이 현상의 정확한 원인·영향·보완 방안이 체계적으로 정리되지 않았다. Claude Code GitHub에서 관련 이슈 7건이 확인되며, 그 중 핵심 이슈(#22264)는 6주째 오픈 상태이다. Bash tool 에러 캐스케이드는 v2.1.80 기준으로도 여전히 미수정이다.

**Q**: Exit code 144의 정확한 원인은 무엇이며, 우리 시스템에서 이 문제를 추가로 완화할 수 있는 구조적 개선이 있는가?

**A**: Exit code 144는 SIGURG(signal 16)에 의한 프로세스 종료이며, Claude Code 내부의 Promise.all 기반 병렬 실행 모델이 원인이다. 우리 시스템에서 7개 task 지시서에 미보호 pkill 패턴이 존재하며, careful-check.sh 훅에 kill 명령 감지가 누락되어 있다. 아래 5개 보완 조치를 권고한다.

---

## 1. 조사 결과: Exit code 144 정체

### 1-1. 수학적 분해
- `Exit code 144 = 128 + 16`
- Signal 16 = **SIGURG** (Linux x86에서는 SIGSTKFLT)
- 표준 SIGTERM(15)이나 SIGKILL(9)이 **아님**

### 1-2. 발생 메커니즘 (2가지)

**메커니즘 A — 내부 하드 타임아웃** (GitHub #34138)
- Bash tool에 `timeout: 600000` 지정해도 **실제 ~48-73초** 하드 시일링 존재
- `BASH_DEFAULT_TIMEOUT_MS`, `BASH_MAX_TIMEOUT_MS` 환경변수 **비기능** (버그)
- 시일링 초과 시 SIGURG(16)로 프로세스 kill → exit code 144

**메커니즘 B — pkill 자기파괴** (GitHub #3068, #13941)
- `pkill -f "패턴"` 실행 시 Claude Code 자신의 Node.js 프로세스 그룹까지 매칭될 수 있음
- 병렬 Bash 호출의 형제 프로세스가 같은 프로세스 그룹에 속하면 함께 종료

### 1-3. 이것은 Claude Code CLI 내부 동작
- Anthropic Messages API에는 "sibling 취소" 개념 없음
- Claude Code의 병렬 실행 오케스트레이터 레이어에서 발생
- 모든 관련 이슈가 `anthropics/claude-code` 리포에 보고됨

---

## 2. 조사 결과: Sibling tool call errored

### 2-1. 핵심 메커니즘
Claude Code는 병렬 tool batch를 **`Promise.all()`로 실행**. 하나라도 reject되면 나머지 전부 취소.

```
Promise.all([Bash_1, Bash_2, Bash_3])
  → Bash_1 실패 (exit ≠ 0)
  → Bash_2, Bash_3 → "Sibling tool call errored" (실제 결과 소실)
```

### 2-2. 4가지 캐스케이드 벡터 (커뮤니티 분석)

- **V1 — 혼합 배치**: 고위험 tool(WebFetch, binary Read)이 저위험(Glob, Grep)을 함께 취소
- **V2 — 무해한 exit 1**: `npm ls`, `grep`, `diff` 등이 정상 동작에도 exit 1 반환 → 캐스케이드
- **V3 — 유령 캐스케이드**: 이전 턴의 캐스케이드가 내부 에러 상태를 오염시켜 다음 턴에서도 단독 호출이 취소됨
- **V4 — MCP EPIPE 크래시**: 취소된 MCP 호출이 stdout 파이프를 닫으면 MCP 서버가 EPIPE로 크래시 → 세션 전체 MCP 영구 장애

### 2-3. Anthropic 공식 수정 현황

- **v2.1.47** (2026-02-18): Write/Edit tool 캐스케이드 수정
- **v2.1.72** (2026-03-10): Read/WebFetch/Glob tool 캐스케이드 수정
- **v2.1.80 현재**: **Bash tool 에러 캐스케이드는 여전히 미수정**
- 핵심 이슈 #22264는 6주째 오픈, Anthropic 공식 응답 없음

---

## 3. 실제 영향 분석

- **데이터 손실**: 파일 쓰기 중 144 발생 → v2.1.47 이후 Write/Edit은 독립 완료됨. 현재 위험 낮음
- **부분 실행**: Bash에서 `&&` 체인 실행 중 캐스케이드로 중단 가능 → 절반만 실행된 상태 잔류 가능
- **세션 오염**: V3(유령 캐스케이드)로 세션 재시작이 필요한 경우 존재
- **MCP 영구 장애**: V4 벡터로 MCP 서버 크래시 시 세션 전체 재시작 필요

---

## 4. 우리 시스템 현황

### 4-1. 이미 적용된 보호 조치 (5건)

1. DIRECT-WORKFLOW.md "병렬 Tool 호출 안전 규칙" 5개 조항 ✅
2. 핵심 스크립트(ci.sh, finish-task.sh, done-watcher.sh) 전부 `|| true` 적용 ✅
3. Claude 훅(pre/post-tool-use.sh) `trap 'exit 0' ERR` 적용 ✅
4. task-253.1.md에서 `pkill ... || true` 안전 패턴 사용 ✅
5. Python os.kill() 호출 전부 try/except 감싸짐 ✅

### 4-2. 미보호 패턴 (발견 7+2건)

**High Risk — pkill 미보호 (7건)**
- task-84.1, 89.1, 90.1, 75.1, 235.1, 236.1.md, dispatch-report-ui-beautify.md
- 패턴: `pkill -f 'python.*server.py'; nohup python3 server.py > /dev/null 2>&1 &`
- `pkill`이 프로세스 못 찾으면 exit 1 → 병렬 호출 시 sibling 전부 취소

**Highest Risk — lsof | xargs kill 미보호 (2건)**
- task-250.1.md, dispatch-dashboard-history-endtime.md
- 패턴: `lsof -ti:8000 | xargs kill && cd ... && python3 server.py &`
- 포트에 프로세스 없으면 xargs kill 실패 → && 체인 중단 + sibling 취소

**Moderate Risk — careful-check.sh 감지 누락**
- rm -rf, DROP TABLE 등은 감지하지만 **pkill/kill -9/xargs kill은 감지 안 함**

---

## 5. 보완 권고 (5건)

### 권고 1: task 지시서 pkill 패턴 표준화
```bash
# 현재 (위험):
pkill -f 'python.*server.py'; nohup python3 server.py > /dev/null 2>&1 &
# 표준 (안전):
pkill -f 'python.*server.py' || true; nohup python3 server.py > /dev/null 2>&1 &
```
- 영향: 7개 task 지시서 (과거 파일이므로 향후 신규 지시서에 적용)

### 권고 2: lsof/fuser 패턴 표준화
```bash
# 현재 (위험):
lsof -ti:8000 | xargs kill && cd ... && python3 server.py &
# 표준 (안전):
lsof -ti:8000 | xargs -r kill 2>/dev/null || true; cd ... && python3 server.py &
```

### 권고 3: careful-check.sh에 kill 명령 감지 추가
- `/home/jay/workspace/hooks/careful-check.sh`에 `pkill`, `kill -9`, `xargs kill` 패턴 추가
- 감지 시 `|| true` 미사용 경고 출력

### 권고 4: DIRECT-WORKFLOW.md 안전 규칙에 명시적 규칙 추가
- 현재 규칙 3번이 `|| true` 패턴 언급하지만 pkill/kill 특별 언급 없음
- 추가 권고: "프로세스 종료 명령(pkill/kill/fuser)은 **반드시 단독 순차 실행** + `|| true` 사용"

### 권고 5: Claude Code 버전 업데이트 모니터링
- #22264 이슈 해결(Bash tool Promise.allSettled 전환) 시 영향 크게 감소
- 현재 v2.1.80 기준 Bash만 남은 상태

---

## 6. 결론: 문제 여부 판단

- **버그인가?** 예. Anthropic이 2차에 걸쳐 부분 수정 출시함. `bug` 라벨 + `has repro` 확인됨
- **우리 시스템에 심각한가?** 중간. 기존 5개 보호 조치로 대부분 커버됨. 미보호 9건은 과거 task 지시서이며, 향후 발생 시 영향 있음
- **즉시 조치 필요?** 권고 4번(워크플로우 규칙 보강)만 즉시 적용 가치 있음. 나머지는 개선 과제로 관리

---

## 발견 이슈 및 해결

### 자체 해결 (0건)
- 본 태스크는 리서치 전용. 코드 변경 없음

### 범위 외 미해결 (3건)
1. **careful-check.sh pkill 감지 추가** — 범위 외 사유: 별도 코드 변경 작업 필요. 아누 판단 후 별도 태스크 생성 권고
2. **과거 task 지시서(7건) pkill 미보호** — 범위 외 사유: 과거 완료 태스크 파일. 향후 신규 지시서부터 적용
3. **DIRECT-WORKFLOW.md 규칙 추가** — 범위 외 사유: 인프라 문서 변경은 아누 승인 필요

---

## 관련 GitHub 이슈 목록

- #22264 — Sibling tool call errored: parallel tool calls cascade-fail (OPEN, 핵심)
- #34138 — BASH_DEFAULT/MAX_TIMEOUT_MS 비기능 + exit 144 (OPEN)
- #24652 — Team Agent 에서 sibling error (OPEN)
- #29770 — Skill tool sibling abort (OPEN)
- #28836 — bypassPermissions 세션 중간 중단 (OPEN)
- #25773 — MCP 에러 메시지 소실 (Closed, duplicate)
- #23332 — v2.1.19 회귀 (Closed, stale)
- #3068 — pkill node 자기파괴 (Closed, NOT_PLANNED)
- #13941 — 광범위 process killer 세션 크래시 (Closed, duplicate)

---

## 생성/수정 파일

- `/home/jay/workspace/memory/reports/task-888.1.md` (본 보고서, 신규)

## 테스트 결과
- 해당 없음 (리서치 전용 태스크, 코드 변경 없음)

## QC 자동 검증
- 아래 별도 실행
