SyntaxError: Unexpected token 'u', "undefined" is not valid JSON (구버전 엔진: Unexpected token u in JSON at position 0) 는 거의 항상 당신이 JSON.parse(undefined) 를 호출했다는 뜻입니다. JavaScript 는 undefined 를 텍스트 "undefined" 로 문자열화하고, 파서는 앞의 u 에 막힙니다. 이유와 고치는 법은 아래.
오류의 모습
// V8 (Chrome / Node / Edge)
SyntaxError: "undefined" is not valid JSON
SyntaxError: Unexpected token 'u', "undefined" is not valid JSON
SyntaxError: Unexpected token u in JSON at position 0 // 구버전 V8
// Firefox
SyntaxError: JSON.parse: unexpected character at line 1 column 1
// Safari
SyntaxError: JSON Parse error: Unexpected identifier "undefined" 위치 0 의 u 는 문자열 "undefined" 의 첫 글자 —— 파서는 실제 데이터를 받지 못한 것입니다.
왜 일어나는가: undefined 를 파싱했음
JSON.parse() 는 인수를 먼저 문자열로 강제 변환합니다. undefined 를 넘기면 리터럴 텍스트 "undefined" 를 파싱하는데, 이는 유효한 JSON 이 아닙니다. 값이 보통 undefined 인 이유:
- 변수나 함수 인수가 한 번도 할당되지 않음
- 객체 속성이 존재하지 않음 (오타 또는 구조 차이):
obj.missing - async 값이 아직 준비되지 않음 (
await전에 파싱) return이 없는 함수를 소스로 사용
고장 난 예제
const cached = localStorage.getItem('settings'); // 키 누락 → null, OK
const draft = window.appState?.draft; // 속성 누락 → undefined
const data = JSON.parse(draft); // ❌ "undefined" is not valid JSON고친 예제
// 파싱 전에 가드
const data = draft ? JSON.parse(draft) : null;
// 또는 안전한 helper
function safeParse(text, fallback = null) {
if (typeof text !== 'string' || text.trim() === '') return fallback;
try { return JSON.parse(text); } catch { return fallback; }
}
const data2 = safeParse(draft); 참고: JSON.parse(null) 은 던지지 않습니다 —— null 을 반환합니다 —— 그리고 localStorage.getItem() 은 누락된 키에 null 을 반환합니다 (undefined 이 아님). 그래서 u 오류는 명확히 undefined 값을 가리키지, 누락된 스토리지 키가 아닙니다.
SyntaxError vs TypeError: 왜 이쪽 이 나오는가
미묘하지만 유용한 디테일: JSON.parse(undefined) 는 SyntaxError 를 던집니다, TypeError 가 아닙니다. 왜? 명세상 JSON.parse 는 먼저 인수를 문자열로 강제 ("undefined") 한 다음 그 문자열을 파싱합니다. 오류는 "이 문자열은 유효한 JSON 이 아니다" 이지 "잘못된 타입을 넘겼다" 가 아닙니다. 그래서 JSON.parse(undefined) 와 JSON.parse("undefined") 가 동일한 "position 0" 메시지를 냅니다.
타입 체크를 정말 하는 API 들과 대조하세요: JSON.stringify(BigInt(1)) → TypeError, 또는 JSON.parse(Symbol()) → TypeError (Symbol 은 문자열로 강제할 수 없음). 파싱 오류를 catch 할 거라면 err instanceof SyntaxError 로 좁혀서 나쁜 데이터 와 나쁜 인수 를 따로 처리하세요.
고치는 법 —— 단계별로
- 입력을 로그하세요:
console.log(typeof src, src)를 파싱 바로 앞에 둡니다.undefined가 찍히면 그게 범인입니다. - 설정되어야 할 곳을 추적 —— 초기화되지 않은 state 필드, 빠진 인수, 또는 객체에 존재하지 않는 속성.
- 가드를 추가 (
if (src)) 또는safeParse폴백, 누락된 값이JSON.parse()에 도달하지 못하게. - async 라면, 파싱 전에 값을
await했는지 확인하세요.
자주 묻는 질문
"Unexpected token u in JSON at position 0" 가 뭔가요?
undefined 를 JSON.parse() 에 넘겼습니다. 문자열 "undefined" 가 되고, 앞의 u 는 유효한 JSON 시작 문자가 아닙니다.
"token o" 나 "token <" 오류와 같은 건가요?
같은 패밀리, 다른 값. u = undefined; token o = 객체가 [object Object] 로 문자열화됨; token < = HTML 응답. 명시된 문자가 실제로 넘긴 게 무엇인지 알려 줍니다.
왜 JSON.parse(null) 은 같은 오류를 안 내나요?
"null" 은 유효한 JSON 이라 JSON.parse(null) 은 null 을 반환합니다. undefined (→ "undefined") 만이 u 오류를 일으킵니다.
지금 바로 고치기
- JSON Fix —— 브라우저에서 JSON 검증 및 수리
- JSON.parse "Unexpected Token" 오류 고치는 법 —— 모든 token 변형
- Unexpected token o in JSON at position 1 —— 객체 쌍둥이 오류
- JavaScript 에서 깨진 JSON 다루는 법 —— safe-parse 패턴