Python CPython 3.14.3에서 파서를 실행해 확인했습니다.
Invalid control character at: line L column C (char N)
문자열 안에 U+0020 미만의 날 문자가 들어 있습니다. 대개는 진짜 줄바꿈이나 탭입니다. JSON은 그것들을 이스케이프하도록 요구합니다. 파이썬에는 그걸 받아들이는 strict=False 옵션이 있지만, 그렇게 나온 문서는 다른 모든 소비자에게 여전히 유효하지 않습니다.
JSON을 붙여넣고 어디서 깨지는지 정확히 확인하기
입력
붙여 넣은 것은 여러분의 브라우저를 떠나지 않습니다. connect-src 허용 목록 덕분에 이는 약속이 아니라 브라우저가 강제하는 보장입니다. 직접 확인하기
실제 원인
어느 쪽이 답인 경우가 많은지, 그 순서대로 정리했습니다.
-
01 문자열 안의 여러 줄 텍스트
로그 발췌, SQL, 스택 트레이스, 템플릿 HTML은 모두 진짜 줄바꿈을 담고 있습니다.
깨지는 예
json.loads('{"sql": "SELECT * FROM t"}')되는 예
json.loads('{"sql": "SELECT *\\nFROM t"}') -
02 f-string이나 이어붙이기로 만든 JSON
끼워 넣은 값은 이스케이프되지 않습니다. dict를 만들고 json.dumps를 쓰면 전부 올바르게 이스케이프됩니다.
깨지는 예
body = f'{{"note": "{note}"}}'되는 예
body = json.dumps({"note": note}) -
03 스프레드시트에서 복사한 탭
눈에 보이지 않고, 복사·붙여넣기를 그대로 살아남습니다.
다른 런타임에서의 같은 실수
밑바탕의 문제는 똑같고, 다른 건 문구뿐입니다. 동료가 이 중 하나를 들고 왔다면, 그 사람이 보고 있는 건 여러분이 보는 것과 같습니다.
| JavaScript (V8) | Bad control character in string literal in JSON at position 11 (line 1 column 12) |
|---|
자주 묻는 질문
- strict=False는 무엇을 하나요?
- json.loads(s, strict=False)는 문자열 안의 제어 문자를 허용합니다. 당장은 넘어가지만 문서는 여전히 유효하지 않은 JSON이고, 뒤쪽에 있는 파이썬 아닌 것들은 앞으로도 계속 거부합니다. 대신 만들어 내는 쪽을 고치세요.