n8n 워크플로우 디버깅은(는) 무엇을 하나요?
시니어 엔지니어처럼 n8n 워크플로우를 고치십시오 — 추측하지 말고 체계적으로.
분류: 먼저 실패 클래스를 식별하세요
사용자에게 묻거나(또는 오류 텍스트에서 유추) 다음 클래스를 확인하세요:
| 클래스 | 증상 | 일반적인 근본 원인 |
|---|---|---|
| 표현식 오류 | Cannot read property X of undefined, 빨간색 노드 배지 | 잘못된 표현식 구문, = 접두사 누락, 정의되지 않은 필드 접근 |
| 타입 불일치 | Expected string, got array, 다운스트림 이상 동작 | Item Lists vs 단일 항목 혼동, Split In Batches 출력 형태 |
| 무음 실패 | 워크플로우는 녹색으로 실행되지만 출력/부작용 없음 | 필터 조건 오류, 고정된 오래된 데이터, 자격 증명 범위 |
| 인증 실패 | 401, 403, Invalid API key | 잘못된 자격 증명 선택, 토큰 만료, OAuth 갱신 미구성 |
| 속도 제한 | 간헐적 429, 수동으로는 작동, 배치에서 실패 | 백오프 없음, 배치 크기 너무 큼, 워크플로우 간 공유 자격 증명 |
| 서브워크플로우 | Execute Workflow가 아무것도 반환하지 않거나 오류 | 매개변수가 전달되지 않음, 반환 값이 설정되지 않음, 잘못된 워크플로우 ID |
표현식 오류
가장 큰 함정: ={{ $json.field }} vs {{ $json.field }}. 앞의 =는 필드를 표현식으로 만듭니다. =가 없으면 리터럴 문자열 {{ $json.field }}가 전송됩니다.
확인:
- 필드를 클릭하세요 — "표현식" 토글(fx 아이콘)이 강조 표시되어 있나요? 그렇지 않으면 리터럴 모드입니다.
- 코드 뷰 JSON에서 값은
=로 시작해야 합니다:"value": "={{ $json.id }}"
정의되지 않은 경로 접근: $json.customer.email은 customer가 null이면 오류를 발생시킵니다. 선택적 체이닝을 사용하세요: $json.customer?.email ?? 'unknown'
이전 노드 참조: $('Node Name').item.json.field를 사용하고, $node['Node Name'].json.field(더 이상 사용되지 않음)를 사용하지 마세요. 공백을 포함한 정확한 노드 이름을 따옴표로 묶으세요.
일반적인 표현식 패턴:
// 배열 접근
{{ $json.items[0].name }}
{{ $json.items?.[0]?.name ?? 'empty' }}
// 이전 노드 출력
{{ $('Webhook').item.json.body.email }}
// 이전 노드의 모든 항목 (반복문용)
{{ $('Split In Batches').all().map(i => i.json.id) }}
// 조건부
{{ $json.amount > 100 ? 'high' : 'low' }}
// 날짜 형식 지정 (n8n은 Luxon 사용)
{{ $now.toISO() }}
{{ $now.minus({ days: 7 }).toFormat('yyyy-MM-dd') }}
// 환경 변수 (자체 호스팅)
{{ $env.MY_SECRET }}
타입 불일치 진단
n8n은 각각 { json: {...}, binary: {...} }를 포함하는 항목 배열로 데이터를 전달합니다. 많은 버그는 단일 항목을 배열로 취급하거나 그 반대의 경우에서 발생합니다.
검사 루틴:
- 실패한 노드의 입력 보기(왼쪽 패널)를 엽니다.
- 확인: 내부에 배열이 있는 하나의 항목(
{ json: { list: [...] } })인가요, 아니면 여러 항목([ { json: {} }, { json: {} } ])인가요? - 이들은 각각 다른 처리가 필요합니다:
- 하나의 항목 안에 배열 →
Item Lists→ "Split Out Items"를 사용하여 펼칩니다. - 이미 여러 항목 → 항목별로 작동합니다.
- 하나의 항목 안에 배열 →
Split In Batches는 메인 출력과 "완료" 출력에서 다른 형태를 출력합니다 — 메인 출력은 배치이고, 완료 출력은 비어 있습니다. 그에 맞게 연결하세요.
무음 실패 — 최악의 유형
워크플로우에 녹색 체크 표시가 있지만 다운스트림에서 아무 일도 일어나지 않았습니다. 진단 순서:
- 실행 데이터 보존 확인. 설정 → "성공적인 실행 데이터 저장"은 디버깅 중에 "모두"여야 하며, "없음"이 아니어야 합니다.
- 각 노드의 출력 검사. 각 노드를 클릭 → "출력" 패널. 데이터가 예상될 때 비어 있는 첫 번째 노드를 찾으십시오.
- 고정 데이터? 노드에 핀 아이콘이 있으면 고정된 테스트 데이터를 반환하는 것이지 실제 데이터가 아닙니다. 마우스 오른쪽 버튼 클릭 → 데이터 고정 해제.
- 필터 / IF 조건.
false로 평가되는IF는 자동으로 분기를 건너뜁니다. 런타임에 조건 값을 확인하십시오. - 자격 증명 범위. Google/Microsoft OAuth 자격 증명은 종종 범위가 제한됩니다. "Google Sheets" 자격 증명으로 Gmail을 읽을 수 없습니다. 올바른 범위로 다시 인증하십시오.
인증 실패
- 이전에 작동하던 워크플로우에서 401 → 토큰 만료. 자격 증명을 다시 인증하십시오.
- 새 워크플로우에서 즉시 401 → 잘못된 자격 증명 유형. 예를 들어 "Header Auth" 대 "OAuth2" — API 문서를 확인하십시오.
- 유효한 토큰으로 403 → 범위 누락 OR 잘못된 계정. OAuth 자격 증명은 계정별로 다릅니다. 올바른 Google/Meta 계정으로 인증했는지 확인하십시오.
자체 호스팅 n8n 특이사항: 컨테이너 재시작 후 자격 증명이 갑자기 작동을 멈추면, 암호화 키(N8N_ENCRYPTION_KEY 환경 변수)가 유지되는지 확인하십시오. 이를 잃으면 모든 자격 증명이 손상됩니다.
속도 제한 실패
증상: 10개 항목에서는 작동하고, 100개 항목에서는 실패합니다. 전형적입니다.
수정 패턴:
- API 호출을
Split In Batches로 감싸고batchSize를 공급업체의 초당 제한과 일치시킵니다. - 배치 사이에
Wait노드를 추가합니다:waitBetweenBatches: ceil(60000 / requests_per_minute) - HTTP Request 노드에
retry.maxTries: 3및retry.waitBetweenTries: 5000을 설정합니다. - 응답 헤더(
X-RateLimit-Remaining,Retry-After)를 확인하고Code노드를 통해 동적으로 백오프합니다.
여러 크론 작업에서 동일한 공급업체를 호출하는 크론 트리거 워크플로우의 경우, 세마포어 패턴(MySQL 행을 잠금으로 사용)으로 하나의 서브워크플로우에 API 호출을 중앙 집중화합니다.
서브워크플로우 실패
Execute Workflow가 null 또는 정의되지 않음을 반환하는 가장 일반적인 이유:
- 부모가 데이터를 전달하지 않음. Execute Workflow 노드에서 "워크플로우 입력"을 확인하십시오 —
{{ $json }}또는 명시적 필드를 참조해야 합니다. - 자식이 출력을 설정하지 않음. 서브워크플로우의 마지막 노드 출력이 반환 값이 됩니다. 마지막 노드가 아무것도 반환하지 않는
MySQL삽입이면 부모는 아무것도 얻지 못합니다. 반환 페이로드를 구성하는 최종Set노드를 추가하십시오. - 잘못된 워크플로우 ID. 서브워크플로우가 삭제되고 다시 생성됨 → 새 ID → 이전 ID 참조가 끊어짐.
n8n 실행 로그 읽기
실행 로그는 노드별 입력과 출력을 보여줍니다. 디버그 패턴:
- 첫 번째 실패 노드(빨간색)를 찾으십시오.
- 해당 노드의 입력(왼쪽)을 보십시오. 예상한 형태인가요?
- 입력이 잘못되었다면 버그는 업스트림입니다 — 거슬러 올라가 추적하십시오.
- 입력이 올바르지만 출력이 잘못되었거나 오류가 있다면 버그는 이 노드 안입니다 — 매개변수를 확인하십시오.
대부분의 버그는 다운스트림 오류로 위장된 업스트림 형태 문제입니다. 오류 메시지는 버그의 위치에 대해 거짓말을 합니다.
일반적인 경우에 대한 빠른 수정 체크리스트
- 표현식이 평가되지 않음 → 앞에
=추가 - 노드가 "처리할 항목 없음"이라고 표시 → 업스트림 IF가 모든 것을 필터링하고 있거나 이전 노드가 빈 값을 반환함
- Google Sheets 추가가 중복을 삽입함 → 고유 제약 조건 없음, 멱등성 확인 추가 ("mysql-checkpointing" 스킬 참조)
- LLM이 잘못된 JSON 반환 → 원시 HTTP에서 스키마를 사용한
Information Extractor로 전환 ("chain-llm-pattern" 스킬 참조) - 웹훅 시간 초과 →
Respond to Webhook뒤로 무거운 작업 이동 (먼저 응답하고, 비동기로 처리)
막혔을 때
사용자에게 다음을 요청하십시오:
- 실행 로그 스크린샷(빨간색 테두리 패널)
- 정확한 오류 메시지(노드에서 복사-붙여넣기)
- 노드의 매개변수(설정 탭, 가능하면 JSON 보기)
- 이전에 작동한 적이 있는지 여부(회귀 vs 새 버그)
이것들 없이 추측하지 마십시오. n8n 오류는 구체적입니다 — 막연한 추측은 시간 낭비입니다.