
JSON.parse의 "Unexpected token" 해결하기: 모든 원인 총정리 가이드
게시일 2026년 7월 23일
SyntaxError: Unexpected token X in JSON at position N은 JavaScript에서 가장 흔한 에러 중 하나이면서 가장 불친절한 에러이기도 합니다. 파서가 어디서 포기했는지는 알려 주지만 왜인지는 알려 주지 않으니까요. 실제로 고치는 방법을 알려 드립니다.
1단계: position 숫자를 읽으세요
JSON.parse는 문자열 시작부터 0부터 문자를 셉니다. JSON이 변수에서 온 것이라면, 다른 무엇을 하기 전에 그 위치 주변의 정확한 조각부터 로그로 찍어 보세요.
try {
JSON.parse(raw);
} catch (e) {
const match = e.message.match(/position (\d+)/);
if (match) {
const pos = Number(match[1]);
console.log(raw.slice(Math.max(0, pos - 20), pos + 20));
}
}
이 스니펫 하나가 JSON 문법에 대한 어떤 조언보다 이 에러를 더 많이 해결해 줍니다. “unexpected token” 에러의 대부분은 사실 “내 문자열에 실제로 뭐가 들어 있는지 모른다” 에러이기 때문입니다. 복사-붙여넣기에서 딸려 온 끝쪽 공백, 템플릿 리터럴에서 생긴 여분의 줄바꿈, 맨 앞의 바이트 순서 표식(BOM) — position 0, 토큰 , 대부분의 편집기에서 보이지 않습니다 — 같은 것들이죠.
실제 발생 빈도순으로 정리한 7가지 원인
- 후행 쉼표.
{"a": 1, "b": 2,}— JS 객체 리터럴에서는 유효하지만 JSON에서는 무효입니다.}나]앞의 쉼표가 단연 가장 흔한 원인입니다. - 큰따옴표 대신 작은따옴표.
{'a': 1}은 JS이지 JSON이 아닙니다. JSON은 키와 문자열 값 모두에 예외 없이 큰따옴표를 요구합니다. - 따옴표 없는 키.
{a: 1}— 역시 JS에서는 유효하지만 JSON에서는 무효입니다. 모든 키에 따옴표가 필요합니다. - 유효한 JSON이 아닌 JS 값.
undefined,NaN, 함수, 주석(// like this) — 이것들은 JSON 명세에는 존재하지 않고 JavaScript에만 있습니다. - 이중 인코딩.
JSON.stringify()를 두 번 호출했거나, 이미 객체인 것을 파싱하려는 경우입니다..parse()를 호출하기 전에typeof raw === 'string'으로 확인하세요. - 빈 문자열 또는
undefined응답. fetch가 조용히 실패했거나 빈 본문을 반환했다면JSON.parse("")는Unexpected end of JSON input이라는, 다르지만 관련된 에러를 던집니다. 파싱하기 전에response.ok를 확인하고 원본 본문을 로그로 찍어 보세요. - 복사-붙여넣기에서 온 BOM이나 보이지 않는 문자. PDF, Word 문서, 일부 터미널 출력에서 JSON을 붙여넣으면 일반 문자와 똑같아 보이는 BOM이나 줄바꿈 없는 공백이 딸려 올 수 있습니다.
가장 빠른 해결책: 디버깅 전에 검증하기
원시 에러 메시지를 한 글자씩 읽는 건 느립니다. position 숫자로 추측하는 대신, 문제의 문자열을 잘못된 문자를 직접 하이라이트해 주는 포매터에 붙여넣으세요. “812번 문자 근처 어딘가”가 “바로 여기, 이 빠진 괄호”로 바뀝니다. (아래에 링크되어 있습니다.)
JSON이 정말로 유효한데도 실패할 때
포매터가 JSON이 문법적으로 올바르다고 확인해 주는데도 JSON.parse가 여전히 에러를 던진다면, 여러분이 넘기는 문자열이 여러분이 생각하는 그 문자열이 아닙니다. 가장 흔한 이유는 응답 본문이 아니라 Response 객체 자체에 .parse()를 호출하는 경우입니다.
// Wrong — parses "[object Response]", not the body
const data = JSON.parse(await fetch(url));
// Right
const data = await (await fetch(url)).json();
// or, if you need the raw text first:
const text = await (await fetch(url)).text();
const data = JSON.parse(text);
빠른 참조표
| 증상 | 유력한 원인 |
|---|---|
Unexpected token } |
닫는 중괄호 앞의 후행 쉼표 |
Unexpected token ' |
큰따옴표 대신 작은따옴표 사용 |
Unexpected token a (또는 아무 글자) |
따옴표 없는 객체 키 |
Unexpected end of JSON input |
빈 문자열, 잘린 응답, 또는 닫히지 않은 괄호 |
Unexpected token (position 0) |
복사-붙여넣기나 Windows에서 저장한 파일의 바이트 순서 표식 |
어느 것도 외울 필요가 없습니다. 해결책은 언제나 같은 세 단계입니다. 보고된 position 주변 조각을 로그로 찍고, 포매터에 돌리고, 포매터가 지목한 그 한 글자를 고치면 됩니다.