밤 시간대의 배치 처리가 정지했다. 다음 날 아침 로그를 보니 아무것도 남아있지 않다. 에러도 없다. 마지막 기록은 전날 밤, 실행 시작 줄뿐이었다.
Claude Code의 claude -p (비대화 모드)을 사용한 무인 실행은 스크립트에서 호출하기 편리하지만, 대화 모드와는 다른 종류의 함정이 있다. 본업으로 AI 자동화 인프라를 구축하면서 실제로 겪었거나 조사하여 밝혀낸 사례 5가지를 정리했다.
이 글을 통해 알 수 있는 것:
- 사용 한도(429)에서의 사일런트 크래시 대처법
- OAuth 인증 만료로 인해 아예 시작조차 할 수 없는 문제
- 워크플로우 에이전트의 '허위 성공' 문제 (v2.1.301에서 수정)
- 작업 스케줄러(Task Scheduler)에서 호출 시 셸 변수가 전개되지 않는 문제
- 턴 수 누적으로 인한 용량 초과 및 도중 종료
claude -p로 실행 중에 Claude Pro/Max의 사용 한도(429 에러)에 도달하면, 프로세스는 종료 코드 1로 종료된다. 문제는 아무런 알림이 오지 않는다는 것이다.
작업 스케줄러나 cron으로 claude -p를 호출하는 경우, 종료 코드 1은 '에러로 종료'를 의미하지만, 이것이 '사용 한도 도달'인지 'OAuth 인증 만료'인지 '코드의 버그'인지는 종료 코드만으로는 알 수 없다. 로그에 아무것도 남지 않는 경우도 있다 (--output-format json의 출력이 중간에 손상될 때).
대처법:
--output-format json으로 출력을 받아, 종료 코드와 JSON 파싱 결과를 별도의 스크립트에서 기록한다. JSON이 손상되었을 경우(파싱 실패)도 기록한다 - 크래시를 감지하면, Claude Code 자체의 PushNotification 도구와는 독립된 경로(ntfy.sh 등의 HTTP 푸시 알림)로 알림을 보낸다. Claude Code 자체가 시작할 수 없는 경우에는 PushNotification 도구도 사용할 수 없으므로 외부 경로가 필요하다.
CLAUDE_CODE_RETRY_WATCHDOG 환경 변수를 설정하면, 한도가 리셋될 때까지 자동으로 대기하며 재시도한다. 다만 리셋 시간이 먼 경우(수 시간 후) 계속 기다릴 수 있다. v2.1.301에서 추가된 CLAUDE_CODE_RETRY_WATCHDOG_MAX_USAGE_LIMIT_WAIT_MS로 최대 대기 시간에 상한을 설정할 수 있게 되었다.
'사용 한도'와 별개로, OAuth 인증 토큰의 유효 기간 만료로 인해 claude -p 자체가 시작되지 못하는 경우가 있다. 이 경우 증상은 비슷하여 '프로세스가 종료 코드 1로 종료된다', '로그에 아무것도 남지 않는다'는 외관을 가질 수 있다.
원인 차이:
- 사용 한도: 프로세스는 시작하지만, Claude API 요청에서 429가 반환된다. -
- OAuth 인증 만료: 프로세스가 시작되지 않거나 시작 직후 종료된다. 'Please run /login'과 유사한 에러가 나타날 때도 있지만, 그렇지 않은 경우도 있다.
인증 만료가 원인일 경우, 함정 1의 '사용 한도 대기 재시도'는 작동하지 않는다. 프로세스가 시작되지 못한 상태에서 재시도를 기다려도 매번 같은 이유로 실패한다.
대처법:
- 인증 상태를 주기적으로 확인하는 메커니즘을 갖춘다. Claude Code 자체의
claude auth status 명령어로 인증 상태를 반환한다 - 인증 만료 알림을 별도의 스크립트로 전송한다.
claude auth status가 이상을 반환하면 즉시 스마트폰으로 알림을 보낸다는 간단한 구성이 효과적이다. -
인증 토큰의 유효 기간을 미리 파악하고, 기한 전에 재인증을 수행한다. OAuth 인증의 유효 기간은 구현에 따라 다르다 (Claude Pro/Max는 Anthropic 계정의 OAuth 토큰. 기간은 길지만, 유효 기간 리프레시에 실패하는 경우가 있다).
Claude Code의 워크플로우 기능(여러 에이전트 단계를 순차적으로 실행)에서, 에이전트가 단계를 실제로 실행하지 않았음에도 불구하고 전체 실행이 '성공'으로 보고되는 버그가 있었다.
이는 v2.1.301 (2026-10-15 공개)에서 수정되었으나, 그 이전 버전을 사용하고 있다면 영향을 받을 가능성이 있다. 증상은 앞서 언급했듯이 '에러 없음, 로그에 성공 기록 있음, 하지만 아무 변화가 없음'이다.
대처법:
- Claude Code 자체를 최신 버전으로 유지하세요. v2.1.301 이후라면 이 특정 버그는 수정되었습니다.
다만, 이것은 '버그 수정'일 뿐이며, '워크플로우 실행 결과를 확인하는' 설계상의 문제는 남아 있습니다. 무인 워크플로우의 결과는 '성공 로그가 있었는지'가 아니라 '기대했던 변화가 실제로 일어났는지'로 확인해야 합니다.
Windows의 작업 스케줄러(또는 유사한 잡 스케줄러)에서 wsl.exe를 경유하여 claude -p를 호출하는 경우, 명령어 문자열에 **셸 변수($id, $VAR, $(command) 등)**을 직접 작성하면 변수가 빈 문자열이 됩니다.
구체적인 예시:
# 이것을 '인수' 필드에 직접 써도 $id는 항상 비어 있게 된다
wsl.exe -d Ubuntu -- bash -lc "for id in 001 002 003; do node script.mjs $id; done"
PowerShell에서 wsl.exe를 호출하든, bash를 직접 호출하든 결과는 같습니다. 작업 스케줄러의 '인수' 문자열을 거칠 때만 발생하는 문제이며, .sh 파일 안에서 변수를 사용하는 형태라면 문제는 없습니다.
대처법:
# 값은 리터럴로 나란히 작성한다
wsl.exe -d Ubuntu -- bash -lc "node script.mjs 001; node script.mjs 002; node script.mjs 003"
# 또는 루프를 .sh 파일 안에 작성하고 그 파일을 호출한다
...
루프나 동적 값이 필요한 경우에는 반드시 셸 스크립트 파일(.sh) 안에 작성해야 합니다. 작업 스케줄러의 '인수' 필드에 셸 변수 확장을 직접 쓰는 것은 피해야 합니다.
이는 claude -p 고유의 문제가 아니라, 작업 스케줄러를 거치는 wsl.exe 호출 전반에 걸쳐 적용되는 사항에 유의하세요.
claude -p는 토큰 소모가 많습니다. 한 세션에서 '같은 파일을 여러 번 읽기', '만약을 위한 확인 반복', '불필요한 검색 누적'과 같은 행동 패턴이 발생하면 턴 수(도구 호출 횟수)가 쌓입니다.
--output-format json 출력에 포함된 numTurns가 그 지표이지만, 주의할 점이 있습니다: 최상위 레벨의 numTurns가 실제 상황을 반영하지 못할 때가 있다. 내부 처리가 다른 카운트로 이루어져 최상위에 올라오지 않는 경우가 확인되었습니다. 실제 토큰 소모는 modelUsage 내역(outputTokens, cacheReadInputTokens)을 확인하는 것이 신뢰성이 더 높습니다. 용량 초과가 발생하면, claude -p는 중간에 종료됩니다. 여기서 문제가 되는 것은 '재실행했을 때, 같은 작업을 다시 할지 여부'입니다. 아무런 장치 없이 재실행하면 이미 완료된 작업을 처음부터 다시 하게 되어 추가적으로 용량을 소모하게 됩니다.
대처법:
- 프롬프트에 '같은 파일을 두 번 읽지 않기', '확인은 주제당 한 번만'과 같이 작업 횟수에 대한 명시적인 제한을 작성합니다.
- 턴별 작업 기록(무엇을 했는지)을 파일에 기록하고, 재실행 시에는 이 기록을 불러와 '이미 완료된 작업'을 건너뜁니다.
- 용량 소모의 실측값을 기록해 두어 어떤 과정이 무거운지 파악하고 필요한 것만 실행하도록 분할합니다.
claude -p에서의 무인 실행은, 대화 모드와 달리 '이상하다'고 느끼는 사람이 없습니다. 따라서 문제가 발생해도 알아차리기까지 시간이 걸리기 쉽습니다.
특히 무서운 것은 '성공하는 것처럼 보이지만 아무 일도 일어나지 않은' 패턴입니다. 이번 5가지 함정 중 1, 3, 5번이 여기에 해당합니다. '에러가 없음'과 '제대로 실행되고 있음'은 별개의 문제입니다.
자동화가 증가할수록, '작동 여부를 확인하는 것' 자체를 시스템으로 구축해야 합니다. 처리 완료가 아니라, 기대했던 변화가 실제로 일어났는지 여부를 확인하는 경로를 별도로 갖는 것이 오랫동안 안정적으로 작동하는 무인 실행 기반의 기본이라고 느끼고 있습니다.
당신의 무인 실행 환경에서 '로그에는 성공했다고 남았지만 실제로는 아무 변화가 없었던' 경험이 있습니까?
참고 기사: