
Claude Code의 심야 자동화에 8일간 헤맸다. 답은 공식 문서에 있었다
요약
Claude Code Desktop의 정기 작업 자동화 과정에서 발생한 승인 대기 오류와 이를 해결하기 위한 8일간의 시행착오를 다룹니다. 문제의 원인은 기능 설명서 미숙지로 인한 조사 절차의 결함이었으며, 공식 문서에 명시된 태스크 단위 권한 설정이 해결책이었습니다.
핵심 포인트
- Claude Code의 정기 작업 중 승인 대기 상태는 에러 없이 무음으로 진행됨
- 승인 대기 중인 세션이 남아 있으면 동일 태스크의 신규 실행이 스킵됨
- 문제 해결을 위해 기능의 공식 문서 정독과 UI 실물 확인이 필수적임
- AI의 답변을 맹신하지 말고 근거(Evidence)와 조사 방법을 지정하여 검증해야 함
요점 (Answer Capsule): 해결책은 8일 전부터 공식 문서에 나와 있었다. 읽지 못한 원인은 조사 절차의 결함 — 기능 설명서를 보기 전에 로그를 파헤쳤기 때문이다.
TL;DR
- Claude Code Desktop의 정기 작업이 승인 대기 상태로 계속 멈춰 있어, 인간과 AI가 8일간 대책을 거듭했다 (allowlist 추가, 명령어 어휘 제약, 지시서 수정, transcript 분석 — 총 8회 이상).
- 그 전 기간 동안, 해결책(태스크 단위의 권한 모드 설정)은 공식 문서에 명시되어 있었다 (존재 시기는 Wayback Machine으로 확인 완료).
- 도달하지 못한 원인은 능력이 아니라 조사 순서: 문제 기능 자체의 문서를 한 번도 열지 않고, 권한 관련 페이지와 로그 분석에만 매달렸다.
- 도중에 "태스크 단위의 권한 모드 설정은 존재하지 않는다"라는 오결론이 확립되었고, 이후의 모든 대책이 그 전제 위에 쌓였다. 근거는 API 스키마뿐이었으며, UI를 확인하지 않았다.
- 얻은 재발 방지책: 제품 기능의 문제는 대책을 세우기 전에 (1) 기능의 공식 문서 정독 (2) 기지 사례의 외부 검색 (3) UI 실물 스크린샷 확인. 아울러 AI에게 질문할 때는 결론의 에비던스(Evidence)와 조사 방법을 지정하여 전달한다.
0. 전제 — 무엇을 하고 있었나
매일 아침 2시에 Search Console 점검, 매일 아침 5시에 기사 생성 — 이 두 가지 정기 작업을 Claude Code Desktop의 스케줄 작업(Routine)으로 돌리려 하고 있었습니다. 둘 다 무인(unattended)을 전제로 합니다. 승인 버튼을 누를 수 있는 인간이 자고 있는 시간대에야말로 실행하고 싶었습니다.
체제는 인간 1명 + AI (Claude Code)입니다. 대책의 설계, 구현, 검증은 주로 AI가 수행하고, 인간이 판단과 승인을 하는 분업 구조입니다. 이 분업 형태가 나중에 영향을 미칩니다.
1. 발생한 일 — 멈추는 방식이 "무음"이었다
허가되지 않은 도구를 호출한 순간, 태스크는 멈춥니다. 다만 그 멈추는 방식이 까다로웠습니다.
- 에러가 발생하지 않는다. 승인 대기 상태가 될 뿐, 모델에는 아무것도 반환되지 않습니다. 따라서 지시서에 "실패하면 대체 수단으로"라고 적어 두어도 발동하지 않습니다 ("실패했다"라는 정보 자체가 전달되지 않기 때문).
- 능동적으로 알려주지 않는다. 정지했음을 나타내는 알림도 에러도 나오지 않습니다 (세션 자체는 사이드바에 남아 있지만, 열어보지 않는 한 승인 대기 중이라는 것을 알 수 없습니다). 아침에 리포트가 없는 것을 보고서야 처음 깨닫게 됩니다.
- 다음 날 이후까지 연쇄적으로 영향을 준다. 멈춘 세션이 남아 있는 동안, 동일한 태스크의 신규 실행은 스킵(Skip)됩니다 (공식 문서에 스킵 이유로 "the previous run was still in progress"라고 명시되어 있습니다). 실측 결과, 승인 대기 중인 세션 1건이 52.4시간 동안 살아남아, 정기 실행을 2일분 차단했습니다 (첫째 날은 종일 실행 없음, 둘째 날은 좀비 세션 종료 직후 4.4시간 지연되어 실행).
사실 이 "실행되지 않는" 현상에 대해, AI (Claude Code)는 당초 "앱이 닫혀 있었기 때문"이라고 설명해 왔습니다. 저는 앱이 계속 가동 중이었다는 것을 알고 있었기에, 듣는 즉시 오류임을 알 수 있었습니다 (실제로 같은 시각에 다른 태스크는 정해진 시간에 실행되었습니다). 진인은 전날의 행(Hang)으로 인한 차단이었습니다. AI는 그럴듯한 설명을, 반례를 찾지 않고 내놓는다. 이번에는 몇 초 만에 바로잡을 수 있었습니다만, 만약 같은 유형의 단정이 나중에 제가 확인할 수 없는 곳(API 스키마)에서 나왔다면, 끝까지 받아들였을 것입니다 (§4). 이 작은 오진이 본 기사의 테마의 축소판입니다.
2. 8일간의 대책 연표 — 모두 "과녁의 바깥"을 맞히고 있었다
| 날짜 | 발생한 일 (실측) | 취한 대책 | 결과 |
|---|---|---|---|
| 07-19 | 완주 22분. 단 심야에 사람이 자리하고 있었던 날 | — | "작동할 때도 있다"라는 잘못된 안도감 |
| 07-20 | Workflow 도구의 승인 대기 시간이 3138.8분 (세션은 52.4시간 생존) | 지시서(Instruction)에서 해당 도구의 필수화 설정을 삭제 | 이 정지 자체는 재발하지 않음. 하지만 행(Hang) 현상이 다음 날 이후의 정기 실행(Scheduled trigger)을 차단함 |
| 07-21 | 정기 실행 없음 | — (AI의 "앱이 닫혀 있었다"는 가설은 즉시 부정됨) | 진인(전날 발생한 행 현상으로 인한 차단)에 도달하지 못함 |
| 07-22 | 행(Hang) 상태였던 07-20분 분량이 아침 승인 직후 종료되었고, 4.4시간 지연된 06:34에 실행됨. 12분 만에 완주 | — | "행 현상이 실행을 막고 있었다"는 것을 보여주는 움직임이었으나, 간과함 |
| 07-23 | for 루프와 $()를 포함한 복합 Bash에서 253.3분 정지 | 사용해도 좋은 명령어 어휘를 지시서에 명문화 | 이 태스크의 Bash 정지는 이후 사라짐 |
| 07-24 | 리포트 쓰기(Write)에서 279.6분 정지 | allowlist에 Write 규칙을 추가 | 효과 없음. 나중에 공식 문서의 기술(accepts the rule but never consults it = 규칙을 수락하지만 참조하지는 않는다)과 일치함을 확인 |
| 07-25 | 14분 만에 완주——하지만 정작 중요한 점검은 미실시 | "무인 완주"라고 집계해 버림 | 완주와 달성의 혼동. 성과를 측정하는 지표가 망가져 있었음 |
| 07-26 | 19분 만에 완주 + 점검 성공. 단 Write에서 12.1분의 정지 발생 | — | "고쳐진" 것처럼 보였음——실제로는 멈추기 직전이었음 |
| 07-27 | 다시 Write에서 96.8분 정지 (쓰기 계열은 이것으로 3번째 횟수 = 07-24/26/27) | settings의 defaultMode를 실측 ("auto"는 무시됨, "acceptEdits"는 주입 성공) | 전진. 하지만 아직 "태스크 측 설정"의 존재를 깨닫지 못함 |
대책의 대부분은 직전의 정지 지점을 확실히 막아주었습니다. 하지만 Write의 allowlist 추가만은 효과가 없었고(애초에 참조되지 않는 규칙이었습니다), 정지 지점은 Workflow → Bash로 이동한 후, Write에 자리를 잡았습니다. 게다가 대책은 지시서 단위로만 적용됩니다. 어휘 제약을 걸지 않았던 자매 태스크(기사 생성)는 07-27에도 복합 Bash에서 151.8분의 승인 대기를 일으켰습니다. 모델은 매번 명령어를 다시 구성하기 때문에, 허가 목록을 나열하는 것만으로는 "열려 있는 요구 사항"을 전부 덮는 것이 원리적으로 불가능합니다. 그 사실을 깨닫기 위해서는 이 방식의 틀 밖으로 나갈 필요가 있었습니다.
3. 전환점 — "같은 문제로 어려움을 겪는 사람을 검색해줘"
8일째 되는 날, 인간 측에서 지시가 내려옵니다. 같은 문제로 어려움을 겪는 사람이 없는지 외부를 검색할 것.
웹 검색을 시작한 지 몇 분 후, 공식 문서인 Schedule recurring tasks in Claude Code Desktop에 다음과 같이 적혀 있는 것을 발견했습니다.
Each task has its own permission mode, which you set when creating or editing the task.
(각 태스크는 고유의 권한 모드를 가지며, 이는 태스크를 생성하거나 편집할 때 설정합니다.)
태스크 편집 폼에 권한 모드 선택기(Picker)가 있었고, "자동(Auto)"을 선택하면 대화 세션과 동일한 자동 승인 방식으로 실행됩니다. 설정 하나였습니다. 실측에서도 즉시, 승인 대기 시간 없이 완주했습니다 (수동 = 인간이 승인할 때까지 정지, 자동 = 6.6~9.4분 만에 무인 완주. 절차와 스크린샷은 실용 편에 수록).
그리고 Wayback Machine으로 과거 문서를 확인해 보니, 이 기술은 늦어도 2026-07-11——장애 대응을 시작하기 8일 이상 전——부터 존재하고 있었습니다. 8일간의 대책은 거의 모두 "답이 적혀 있는 페이지를 읽었더라면 불필요했을" 것들이었습니다.
해결을 확인한 인간 측에서 이어서 다음 숙제가 나왔습니다. 왜, 더 빨리 이곳에 도달할 수 없었는가. 여기서부터는 그 검증입니다.
4. 오결론의 해부 — "존재하지 않음"은 어떻게 만들어졌는가
대책이 계속해서 과녁을 빗나간 가장 큰 이유는 초반에 확립한 하나의 오결론 때문이었습니다.
"태스크 단위의 권한 모드 지정은 존재하지 않는다"
그 근거는 태스크 생성·업데이트 API의 스키마입니다. 파라미터는 taskId / prompt / description / cronExpression / fireAt / notifyOnCompletion——권한 모드(permission mode) 항목은 없습니다. 이를 통해 「존재하지 않는다」라고 결론지었습니다.
하지만 「API에 항목이 없다」는 것이 의미하는 바는 「이 API를 통해서는 설정할 수 없다」는 것뿐이었습니다. 설정은 UI(태스크 편집 폼)에 존재했습니다. 탐색한 범위(API 스키마)와 주장한 범위(기능 전체)가 어느샌가 뒤바뀌어 있었던 것입니다.
이 오결론은 강력했습니다. 「태스크 측에는 설정이 없다」가 전제가 되자, 남은 길은 settings의 허용 목록(allowlist)을 키워나가는 것뿐이 되었고, 이후의 모든 대책이 그 틀 안에서 설계되었습니다. 틀 자체를 의심할 계기는 외부로부터의 질문(「왜?」)이 들어오기 전까지 없었습니다.
5. 왜×5 — 근본 원인까지 파고들기
왜 해결책을 깨닫지 못했는가 → 사용 중인 기능(스케줄 태스크) 자체의 공식 문서 페이지를 8일 동안 아무도 열어보지 않았다. 읽은 것은 permissions / permission-modes / headless라는 「권한 계열」 페이지뿐이었다 -
왜 기능 페이지를 열어보지 않았는가 → 문제를 조기에 「권한 설정 문제」로 프레이밍(framing)하여, 조사 대상이 해당 레이어에 고정되었다. 증상이 속한 층은 파고들었지만, 증상이 일어나고 있는 문맥(기능)은 파고들지 않았다 -
왜 프레이밍이 고정되었는가 → 초기 대책(도구 필수화 삭제·커맨드 어휘 제약)이 실제로 중단을 줄였고, 「방향은 맞다, 나머지는 구멍을 메우기만 하면 된다」라는 확증을 강화했다. 게다가 §4의 오결론이 틀의 벽이 되었다 -
왜 오결론이 생겼는가 → API 스키마만 보고 「항목이 없다 → 존재하지 않는다」라고 비약했으며, UI 확인(편집 폼을 열거나 스크린샷을 보는 것)을 하지 않았다. 존재하지 않는다는 주장에 탐색한 범위를 명시하지 않았다 -
(근본) 왜 그것이 8일 동안 통했는가 → 조사 표준 절차에 「기능의 공식 문서 전독(全讀)」, 「기존 사례의 외부 검색」, 「UI 실물 확인」이 없었으며, 내부 관측(로그·설정·스키마 분석)에 편중되어 있었다. 잘 다루는 도구로 파낼 수 있는 곳만을 계속해서 파고 있었다
6. 인간과 AI의 맹점은 보완이 아니라 증폭되었다
이 실패는 인간과 AI의 협업 과정에서 발생했습니다. 그리고 분업이 맹점을 상쇄하는 방향이 아니라 증폭하는 방향으로 작용했습니다.
AI는 내부 관측에 능숙하며 빠르다. transcript 분석, 설정 파일 검증, API 스키마 확인——수 분 만에 방대한 양을 처리했고, 그 결과로서 「존재하지 않는다」를 자신 있게 단정했다. 인간은 그 단정을 전제로 판단했다 -
UI 측에도 함정이 있었다. 권한 모드 피커(picker)는 「권한 모드」라는 라벨이 아니라, 현재의 모드 명칭(「수동」 등)으로 표시된다. 인간은 매일 그 화면을 보고 있었음에도 그것이 설정 항목이라고 인식하지 못했다 (이 UI의 불친절함은 실제 장벽이며, 우리만의 문제는 아니라고 생각합니다) -
그리고 AI는 화면을 볼 수 없다. 인간이 보고 있는 UI를 AI는 확인할 수 없다——「스크린샷을 주세요」라고 말하지 않는 한. 실제로 마지막에는 편집 폼 스크린샷 한 장을 공유한 지 몇 분 만에 해결되었다
내부 관측에 능한 AI + UI를 보고 있는 인간이라는 조합은, 양측의 담당 경계에 있는 것(UI 안의 설정 항목)을 「둘 다 보고 있지 않은」 상태로 만들었습니다. 역할 분담은 경계의 소유자를 정하지 않는 한, 경계를 맹점으로 만듭니다.
7. 동일한 유형의 실패가 4연쇄로 일어났다
이 장애 대응 과정에서 기록한 실패(RCA)는 4건이 있습니다. 나열해 보면 동일한 구조를 가지고 있습니다.
반례를 찾지 않고 인과를 작성했다 — 중단 원인 설명을 실측 데이터의 상관관계로부터 작문했고, 공개 전 독립 감사에서 인과 설명 3건이 모두 오류임이 판명되었다 (수치·시각·인용은 모든 항목이 일치했음에도 불구하고 말이다) -
완주와 달성을 혼동했다 — 태스크가 「끝났다」는 것을 「점검할 수 있었다」로 계산했다. 반증(리포트 내의 「미점검」이라는 글자)은 처음부터 손에 쥐고 있었다 -
기구의 동작을 목적의 대리물로 삼았다 — 「거부가 올바르게 반환되는가」를 검증하려다 「목적의 작업이 실행되는가」를 보지 않았다 -
그리고 문서를 읽지 않았다 — 본 기사
전부, 검증을 생략한 곳에 확증이 자리 잡는다는 동일한 병증입니다. 측정하기 쉬운 것·조사하기 쉬운 것에 검증이 편중되었고, 생략한 쪽(반례·달성·목적·외부 정보)에 구멍이 생겨났습니다.
8. 재발 방지 — 운영에 도입한 규칙
AI의 지시서(CLAUDE.md)에 다음 규율을 추가했습니다.
문제 조사는 "기능 우선(Function First)": 제품 기능에 관한 문제는 대책을 세우기 전에 (1) 해당 기능의 공식 문서 페이지를 정독 (2) 기지 사례의 외부 검색 (GitHub issues 등) (3) UI 실물 확인 (스크린샷 요청)을 완료할 것. "존재하지 않는다・할 수 없다"라고 결론 내릴 때는 탐색한 범위를 명시하고, 미탐색 영역은 "미확인"으로 남길 것. 내부 관측(로그·설정·스키마)만으로 대책을 쌓지 말 것.
가장 효과적인 것은 "탐색 범위의 명시"라고 생각합니다. "X는 존재하지 않는다"라고 쓸 때, "어디를 찾아봤는데 없었는지"를 쓰게 합니다. 이번 사례라면 "API 스키마에는 없음 (UI는 미확인)"이라고 쓰는 순간, 다음에 조사해야 할 장소가 자명해집니다.
또 하나, 인간 측의 질문 방식도 바꿨습니다. "권한 모드를 이렇게 바꾸고 싶어" "이 정지를 고쳐줘"와 같이 지금 곤란한 점만 물으면, AI가 추측(Hallucination)을 통해 그럴듯하게 대답할 여지가 생깁니다. 지난 8일간의 잘못된 설명——"앱이 닫혀 있었다" "태스크 단위의 설정은 존재하지 않는다"——는 둘 다 근거를 덧붙이지 않은 채 나온 단정이었습니다. 이제는 결론에 에비던스(Evidence)를 요구하고, 조사 방법까지 덧붙여서 묻습니다. "공식 문서에서 확인해줘" "동일하게 곤란해하는 사람이 없는지 조사해줘". 질문만 던지지 않고, 검증 절차와 함께 전달합니다.
9. 요약
- 패인은 능력이 아니라 조사의 순서. 로그를 파헤치기 전에 설명서를 읽었더라면 8일간의 대책은 거의 불필요했을 것입니다. 새로운 기능일수록 "문서에는 아직 안 적혀 있겠지"라고 생각하기 쉽지만, 실측 결과 문서가 8일 앞서 있었습니다.
- AI에게 물을 때는 지금 곤란한 점만 던지지 말 것. 결론에 대한 에비던스를 요구하고, "공식 문서에서 확인해줘"와 같이 조사 방법을 덧붙일 것——추측성 즉답을 방지합니다.
- 오늘 바로 시도할 수 있는 1가지 액션: 지금 트러블슈팅 중인 기능이 있다면, 그 기능의 공식 문서를 처음부터 끝까지 읽으세요. 15분이면 끝납니다. 우리의 8일보다 훨씬 짧습니다.
FAQ
Q. AI에게 조사를 시켰는데, 왜 문서 누락이 발생했는가?
AI는 주어진 틀(권한 설정 문제) 안에서는 철저하게 조사하지만, 틀 자체를 의심하는 움직임은 여전히 약했습니다. 게다가 내부 관측(로그·스키마 분석)은 AI의 특기 분야이며 매번 어느 정도 성과가 나오기 때문에, 궤도를 수정할 계기가 생기지 않았습니다. 대책으로서 "기능 문서를 정독한 후 대책을 세운다"라는 절차를 AI 지시서 측에 규율로 작성하여, 틀 밖을 강제적으로 탐색하게 했습니다. 이와 함께 인간 측도 AI의 결론에 에비던스를 요구하고, 조사 방법("공식 문서에서 확인해줘" 등)을 덧붙여 질문하는 운영 방식으로 바꾸었습니다.
Q. "API에 없으니까 존재하지 않는다"는 그렇게 부자연스러운 추론인가?
추론 그 자체보다, 부존재를 주장할 때 탐색 범위를 덧붙이지 않은 것이 문제입니다. "API 스키마에는 없음 (UI는 미확인)"이라고 써두기만 했어도 읽는 사람(미래의 자신 포함)이 빈틈을 알아챌 수 있었습니다. 또한 순서가 반대—UI를 먼저 확인한다—였다면 몇 분 만에 끝났을 일입니다.
Q. 실측이나 로그 분석은 헛수고였는가?
헛수고가 아닙니다. 문서의 기술 내용을 자신의 환경에서의 사실로 확정한 것은 실측입니다 (발화 블록의 연쇄·defaultMode: "auto" 무시). 또한 모델에는 정말 아무것도 반환되지 않는다는 점, 태스크 측의 설정이 settings의 defaultMode를 덮어쓰며 기동했다는 점 등, 실측으로만 얻을 수 있었던 지견도 있었으며, 해결 후의 검증(세션의 permissionMode 필드 확인)에도 그대로 사용할 수 있었습니다. 문제는 실측만으로 전선을 구축했다는 점입니다. 외부 정보(문서·기지 사례)와 내부 관측은 병행해야 하는 것이었습니다.
Q. 그래서, 결국 어떻게 설정해야 하는가?
실용편에 정리해 두었습니다. 설정 절차·피커 위치 스크린샷·모드별 실측 비교·"자동"으로 설정해도 남는 함정까지.
환경
- Claude Code Desktop (Windows 11). 실측 시의 코어는 07-19~26이 2.1.123, 07-27 이후(해결 시 포함)가 2.1.219 (모두 세션 transcript의
version
필드의 기록값) - 인용한 공식 문서(official documentation)는 집필 시점의 버전입니다. 해결책에 대한 기술이 장애 기간 이전부터 존재했다는 사실은 Wayback Machine의 스냅샷을 통해 확인했습니다: http://web.archive.org/web/20260711134609/https://code.claude.com/docs/en/desktop-scheduled-tasks
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기