Claude Code 오류 메시지 해독법: 로그를 재현 가능한 수정으로 바꾸는 실전 흐름
Claude Code로 스택 트레이스, TypeScript, Kubernetes, CI 로그를 재현 절차와 검증 명령으로 정리하는 방법.
Claude Code를 처음 쓰면 긴 오류 메시지를 붙여 넣고 “이거 고쳐줘”라고 말하고 싶어집니다. 가끔은 맞지만, 안정적인 방법은 아닙니다. Claude Code는 방금 실행한 명령, 환경 변수, 패키지 버전, CI 환경의 차이를 자동으로 알 수 없습니다. 좋은 흐름은 오류를 맞히게 하는 것이 아니라, 재현 가능한 버그 보고서로 바꾸고 다음 확인 명령까지 좁히는 것입니다.
이 글은 TypeScript 타입 오류, Node.js 스택 트레이스, 런타임 로그, Docker/Kubernetes 로그, GitHub Actions 실패를 Claude Code로 분석하는 실전 흐름을 다룹니다. 기본 사용법은 Claude Code common workflows, 문제 해결은 Claude Code troubleshooting, 팀 설정과 권한은 Claude Code settings를 함께 확인하세요.
핵심 흐름: 추측이 아니라 재현
오류 메시지는 수수께끼가 아니라 증거입니다. 마지막 세 줄만 보는 대신 실패한 명령과 전체 로그를 남겨야 합니다.
flowchart TD
A["실패한 명령 출력 저장"] --> B["전체 로그는 보존하고 노이즈만 줄이기"]
B --> C["Claude Code에 가설과 재현 절차 요청"]
C --> D["최소 실패 사례 만들기"]
D --> E["수정 후 같은 명령 재실행"]
E --> F["테스트나 CLAUDE.md에 재발 방지 기록"]
| 오류 종류 | Claude Code에 줄 자료 | 기대하는 출력 | 사람이 검증할 것 |
|---|---|---|---|
| TypeScript | 전체 tsc --noEmit --pretty false 출력과 파일 경로 | 깨진 타입 계약, 안전한 수정, 피해야 할 수정 | any나 ts-ignore로 숨기지 않았는지 |
| Node.js stack trace | 첫 Error 줄, 앱 코드 frame, 입력값 | 첫 번째 유용한 앱 frame, 재현 조건 | 같은 입력으로 로컬 재현 |
| Docker/Kubernetes | describe, 이전 로그, events | OOM, env, probe, image, app 오류 분류 | 증거 줄과 확인용 kubectl 명령 |
| GitHub Actions | 실패 job 로그, 변경 파일 | 실패 step, 로컬 재현 명령, CI 차이 | 로컬과 CI가 모두 통과 |
사용 사례1: npm과 tsc 오류 저장
먼저 원본 출력을 잃지 않는 것이 중요합니다.
mkdir -p tmp/error-cases
npm test 2>&1 | tee tmp/error-cases/test.log
npx tsc --noEmit --pretty false 2>&1 | tee tmp/error-cases/tsc.log
그다음 Claude Code에는 정답이 아니라 조사 계획을 요청합니다.
claude -p "
I need a reproducible fix, not a guess.
Read these files if they exist:
- tmp/error-cases/test.log
- tmp/error-cases/tsc.log
Return:
1. One-line failure summary
2. Likely root cause with confidence level
3. Minimal reproduction steps
4. Next 3 commands to run
5. Smallest safe code change to try
6. Verification command after the fix
Do not hide TypeScript errors with any or ts-ignore.
"
confidence level을 요구하면 Claude Code가 확신하지 못하는 부분을 드러낼 수 있습니다. 확률이 낮다면 패치보다 다음 확인 명령이 먼저입니다.
사용 사례2: Node.js 스택 트레이스 줄이기
Node.js 로그는 node_modules frame이 많아 읽기 어렵습니다. 원본은 보관하고, 분석용 짧은 버전을 따로 만듭니다.
// scripts/minimize-stacktrace.mjs
import { readFileSync } from "node:fs";
const input = readFileSync(0, "utf8");
const lines = input.split(/\r?\n/);
const kept = [];
let dependencyFrames = 0;
for (const line of lines) {
const isStackFrame = /^\s+at /.test(line);
const isDependencyFrame = line.includes("node_modules");
if (!isStackFrame || !isDependencyFrame || dependencyFrames < 3) {
kept.push(line);
}
if (isStackFrame && isDependencyFrame) {
dependencyFrames += 1;
}
}
const important = kept.filter((line) =>
/Error:|TypeError:|ReferenceError:|SyntaxError:|Caused by:|^\s+at |src\/|app\/|packages\//.test(line)
);
console.log(important.slice(0, 80).join("\n"));
node scripts/minimize-stacktrace.mjs < tmp/error-cases/test.log > tmp/error-cases/test.min.log
claude -p "
Analyze tmp/error-cases/test.min.log first.
If the minimized log is not enough, ask for the full log instead of guessing.
Explain:
- Which application frame is the first useful frame
- What input or state is needed to reproduce it
- Whether this looks like async timing, null data, missing env, or dependency mismatch
- The smallest test that would fail before the fix
"
이 스크립트는 진단기가 아닙니다. 의존성 frame을 줄여서 앱 코드의 첫 단서를 보이게 할 뿐입니다.
사용 사례3: TypeScript 오류를 계약 위반으로 읽기
Type X is not assignable to type Y는 대개 호출자가 넘긴 데이터 형태와 함수가 기대한 데이터 형태가 다르다는 뜻입니다. 타입은 코드 사이의 계약입니다.
claude -p "
Explain this TypeScript error as a broken contract between caller and callee.
Use this output:
$(npx tsc --noEmit --pretty false 2>&1)
Return a table with:
- Error location
- Plain Korean explanation
- Data shape expected
- Data shape actually provided
- Safe fix
- Risky fix to avoid
Do not suggest any, ts-ignore, or disabling strict mode unless there is no other option.
"
이렇게 요청하면 컴파일러를 조용하게 만드는 수정과 실제 버그를 고치는 수정을 분리할 수 있습니다. User | null 오류라면 강제 캐스팅보다 로그아웃 상태 처리, API 응답 검증, 테스트 fixture 수정이 먼저입니다.
사용 사례4: Kubernetes 로그를 확인 명령으로 바꾸기
CrashLoopBackOff는 원인이 아니라 결과입니다. 먼저 pod 설명, 이전 로그, 이벤트를 모읍니다.
kubectl get pod -n app
kubectl describe pod web-abc123 -n app > tmp/error-cases/pod.describe.txt
kubectl logs web-abc123 -n app --previous > tmp/error-cases/pod.previous.log
kubectl get events -n app --sort-by=.lastTimestamp > tmp/error-cases/events.log
claude -p "
Triage this Kubernetes crash.
Files:
- tmp/error-cases/pod.describe.txt
- tmp/error-cases/pod.previous.log
- tmp/error-cases/events.log
Return:
1. Most likely category: OOMKilled, missing env, image pull, app exception, probe failure, or dependency outage
2. Evidence lines from the logs
3. One kubectl command to confirm each remaining hypothesis
4. Temporary mitigation
5. Permanent fix
6. Rollback check
If evidence is insufficient, say what command is missing.
"
답변에 증거 줄이 없다면 아직 결론이 아니라 가설입니다.
사용 사례5: GitHub Actions 실패 분석
CI 로그의 마지막 부분은 연쇄 오류인 경우가 많습니다. 실패 job과 step, 실제 실패 명령을 먼저 분리합니다.
gh run list --limit 5
gh run view RUN_ID --log > tmp/error-cases/github-actions.log
claude -p "
You are triaging a GitHub Actions failure.
Analyze tmp/error-cases/github-actions.log and return:
1. Failed job and failed step
2. Exact command that failed
3. Whether this should reproduce locally
4. Local reproduction command
5. CI-only differences to inspect: Node version, env vars, cache, timezone, OS, permissions
6. Smallest patch to try
7. Verification plan for local and CI
Do not assume the root cause if the log only shows a downstream symptom.
"
이 방식은 flaky test, timezone 차이, secret 누락, 캐시 문제를 나눠 보는 데 유용합니다.
복사해서 쓰는 버그 보고 템플릿
# Bug report: short title
## Goal
What I was trying to do:
## Environment
- OS:
- Node version:
- Package manager:
- Branch:
- Commit:
## Exact command
```bash
paste the exact command here
```
## Expected result
What should have happened:
## Actual result
What happened instead:
## Logs
Paste the full error or attach the saved log file path.
## Minimal reproduction
Smallest steps that still fail:
## What I already tried
- Attempt 1:
- Attempt 2:
## Verification plan
Command that must pass after the fix:
흔한 함정
마지막 세 줄만 붙여 넣지 마세요. 원인은 중간 stack에 숨어 있는 경우가 많습니다.
실행한 명령을 생략하지 마세요. npm test와 특정 파일만 실행한 vitest --run은 완전히 다른 맥락입니다.
TypeScript 오류를 any, ts-ignore, strict mode 해제로 덮지 마세요. 긴급 우회가 필요할 때도 있지만 기본값이 되어서는 안 됩니다.
로그에 API key, Cookie, JWT, DB URL을 넣지 마세요. 팀에서는 공식 settings 문서를 보고 권한과 설정을 먼저 정리하세요.
수정 후에는 먼저 실패했던 같은 명령을 다시 실행하세요. 그다음 lint, build, CI로 넓히면 됩니다.
ClaudeCodeLab 템플릿, 교육, 상담
개인이라면 이 글의 prompt만 복사해도 충분히 시작할 수 있습니다. 팀에서는 어떤 로그를 공유해도 되는지, 어떤 수정은 금지할지, CI 실패를 어떻게 분류할지, reviewer가 어떤 증거를 요구할지 정해야 합니다.
ClaudeCodeLab은 재사용 가능한 디버깅 prompt, 버그 보고 템플릿, CI triage 체크리스트, CLAUDE.md 운영 규칙을 정리할 수 있도록 Claude Code 제품과 템플릿 및 Claude Code 교육과 상담을 제공합니다.
관련 글: Claude Code 오류 진단, Claude Code 디버깅 기법, Claude Code 로그와 모니터링.
정리
Claude Code로 오류 메시지를 잘 읽는 핵심은 더 잘 추측하게 만드는 것이 아닙니다. 실패 명령, 전체 로그, 최소 재현, 확인 명령, 검증 계획을 제공해서 실행 가능한 다음 단계로 바꾸는 것입니다.
이 글의 방법을 실제 ClaudeCodeLab 유지보수에 적용해 보니, Masa는 디버깅 첫 10분에서 가장 큰 효과를 봤습니다. tsc --pretty false 출력 저장, 원본을 보존한 stack trace 축약, CI 실패를 job, step, command, reproduction으로 나누는 습관 덕분에 Claude Code의 제안을 맹신하지 않고 같은 명령으로 검증하며 수정할 수 있었습니다.
무료 PDF: Claude Code 치트시트
이메일을 입력하면 명령, 리뷰 습관, 안전한 워크플로를 정리한 PDF를 받을 수 있습니다.
개인정보를 안전하게 관리하며 스팸을 보내지 않습니다.
작성자 소개
Masa
Claude Code 실무 워크플로와 팀 도입을 검증하는 엔지니어입니다.
관련 글
Claude Code 권한 세이프티 래더: 통제력을 잃지 않고 allow 넓히기
read-only에서 제한 편집, 검증 명령, deploy 확인까지 권한을 단계적으로 넓히는 방법.
Claude Code Small PR Proof Pack: 작은 PR을 리뷰 가능한 상태로 만드는 증거 세트
Claude Code의 작은 PR에 diff, 검증, 공개 URL, CTA 경로, rollback을 붙이는 실무 체크리스트.
Claude Code 커밋 전 리뷰 게이트: diff, 테스트, 공개 URL, CTA 확인
Claude Code 작업을 커밋하기 전에 diff 범위, build, 공개 URL, Gumroad 링크, 상담 CTA, 테스트 누락과 무관한 파일을 확인하는 방법입니다.