
Claude Code가 API Error 500으로 멈추는 문제와 자동 리커버리 (Automatic Recovery) 설계 사상
요약
Claude Code 사용 중 API Error 500으로 인해 작업이 중단되는 문제를 해결하기 위한 설계 사상과 자동 복구(Automatic Recovery) 구현 방법을 소개합니다. 이 문제는 서버 부하로 인한 확률적 오류이며, 기존의 알림이나 단순 재시작 방식은 대화 컨텍스트 유지에 한계가 있습니다. 따라서 `expect` 명령어를 사용하여 Claude 실행을 래핑(Wrapping)하고, 500 에러 발생 시 자동으로 '계속해 주세요'와 같은 프롬프트를 전송하여 대화의 연속성을 유지하는 자동 복구 시스템을 구현했습니다. 이 방법은 터미널 환경에만 적용 가능하며, VSCode 확장 사용자에게는 Anthropic 측의 개선이 필요합니다.
핵심 포인트
- API Error 500은 서버 부하로 인한 확률적 오류이며 근본적인 해결책은 어려움.
- 단순 재시작 방식은 대화 컨텍스트를 소실시키므로, 연속성을 유지하는 것이 핵심 목표임.
- `expect` 명령어와 스크립트 래핑을 통해 500 에러 발생 시 자동으로 '계속해 주세요' 메시지를 전송하여 작업을 재개할 수 있음.
- 자동 복구 메커니즘은 터미널 환경(CLI)에만 유효하며, VSCode 확장 사용자에게는 적용되지 않음.
Claude Code를 사용하다 보면 이런 경험이 있지 않은가.
장시간 태스크를 의뢰하고 자리를 비웠다가 돌아와 보니 아무것도 끝나 있지 않다. 터미널에는 API Error: 500 메시지가 출력된 채로 Claude가 멈춰 있다.
이는 미국 시간으로 야간(일본 시간으로 낮)에 서버 부하가 높아지기 쉬우며, 확률적으로 500 에러가 발생하기 때문이다. Claude Code는 에러 발생 시 응답을 멈추지만, UI 상으로는 '생각 중'으로 보이기 때문에 사용자가 알아차리기 어렵다.
이 기사에서는 이 문제에 어떻게 대응할 것인가에 대한 설계 사상과, 터미널 사용자들을 위한 자동 리커버리 (Automatic Recovery) 구현을 소개한다.
먼저 "무엇이 곤란한가"를 정리한다.
- API Error 500은 확률적으로 발생한다 (서버 측 문제이므로 근본적인 해결이 불가능하다)
- 멈춰도 UI 상으로는 알아차리기 어렵다
- 특히 자리 비움/취침 중에 장시간 태스크를 의뢰했을 경우, 알아차리지 못한 채 작업이 공중에 붕 뜨게 된다
Claude Code에는 Stop 이벤트의 hook이 있다. 멈춘 순간에 데스크톱 알림을 보내는 것은 가능하다.
"hooks": {
"Stop": [{
"type": "command",
...
한계: "알아차리는 것"뿐이다. 자리 비움/취침 중에는 무의미하다.
launchd나 cron으로 프로세스를 감시하여, 죽어 있다면 재시작하는 안.
한계: 재시작해도 대화 컨텍스트 (Conversation Context)가 사라진다. "무엇을 해야 할지 모르는 Claude"가 실행될 뿐이다.
장시간 태스크를 서브 에이전트 (Sub-agent)에게 맡겨서, 메인 세션에 미치는 영향을 줄이는 안.
한계: 서브 에이전트는 실행될 때마다 토큰 주입 비용이 발생한다. 장시간 태스크 전체를 위임하는 것은 비현실적이다.
expect 명령어를 사용하여 claude를 래핑 (Wrap)하고, API Error: 500이 나오면 자동으로 "계속해 주세요"를 전송한다.
장점: 대화 컨텍스트를 유지한 채로 재개할 수 있다.
트리거를 500으로 한정하는 이유:
| 에러 코드 | 의미 | 킥 (Kick) 해야 하는가 |
|---|---|---|
| 400 | 요청 측의 문제 | ❌ 반복해도 무의미 |
| ... |
킥 제어:
- 킥 간격 60초: 서버 부하가 높을 때 연타하지 않음
- 연속 에러 상한 3회: "킥을 했는데도 500이 지속된 횟수"를 카운트. 3회 시 정지
- 정상 응답이 오면 카운트 리셋
#!/usr/bin/env expect
# claude-watchdog.sh — API Error 500을 감지하여 자동으로 킥하는 expect 래퍼
set kick_interval 60
...
운영 환경에 부하를 주지 않고 테스트하기 위한 모크 (Mock) 스크립트.
#!/bin/bash
# mock-claude.sh — 테스트용 모크
INTERVAL=${FAST:+10}
...
실행:
# FAST=1로 10초 간격 (통상 65초 대신)
FAST=1 CLAUDE_CMD=./mock-claude.sh ./claude-watchdog.sh
# ~/.zshrc 에 추가
alias claude='~/.claude/scripts/claude-watchdog.sh'
이 부분이 가장 중요한 점이다.
이 watchdog은 터미널에서 claude 명령어를 입력했을 경우에만 유효하다.
VSCode의 Claude Code 확장은 독자적인 프로세스로 동작하고 있으며, ~/.zshrc의 에일리어스 (Alias)는 적용되지 않는다. VSCode 확장이 500 에러로 멈춘 경우, 이 메커니즘은 무관하다.
VSCode 확장 사용자에게 현실적인 답은 현재로서는 없다. Anthropic 측의 개선을 기다리는 것이 솔직한 심정이다.
| 수단 | 효과 | 한계 |
|---|---|---|
| Stop hook 알림 | 멈춘 것을 알아차릴 수 있음 | 자리 비움 중에는 무의미 |
| ... |
500 에러는 서버 측 문제이므로 근본적인 해결은 할 수 없다. 할 수 있는 일은 "멈췄을 때의 손실을 최소화하는" 설계를 쌓아가는 것이다.
터미널에서 claude를 사용하는 사람에게는 expect watchdog이 유효한 선택지가 된다. VSCode 확장 사용자는 현재로서는 수동 재전송이 유일한 대책이다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기