Claude Code로 한창 작업하다가 갑자기 아래와 같은 오류가 뜨면서 응답이 끊기는 경우가 있다.
API Error: 400 The request body is not valid JSON:
no low surrogate in string: line 1 column 1025146 (char 1025145)
코드를 잘못 짠 것도 아니고, 네트워크가 끊긴 것도 아니다. 그런데 이후 어떤 명령을 넣어도 같은 오류가 반복된다. 이 글은 이 오류가 왜 나는지, 그리고 어떻게 벗어나는지를 정리한 것이다.
결론부터
Claude Code가 API로 보내는 요청 본문(JSON) 안에 깨진 유니코드 문자가 섞여 있어서 서버 쪽 JSON 파서가 요청 자체를 거부한 것이다. 대부분은 /clear로 세션을 초기화하면 해결된다. 특정 파일이 원인이면 그 파일의 인코딩을 고치면 된다.
왜 “low surrogate”인가
유니코드에서 이모지나 일부 특수문자(BMP, 즉 U+FFFF 밖의 문자)는 하나의 코드 단위로 표현할 수 없다. 그래서 서로게이트 쌍(surrogate pair) 이라는 두 개의 코드 단위로 표현한다.
- high surrogate: U+D800 ~ U+DBFF
- low surrogate: U+DC00 ~ U+DFFF
이 둘은 반드시 짝으로 붙어 다녀야 한다. 그런데 어떤 이유로 high surrogate만 남고 뒤에 와야 할 low surrogate가 사라진 문자열이 JSON 본문에 들어가면, 파서 입장에서는 유효하지 않은 문자열이므로 no low surrogate in string 오류를 낸다.
오류 메시지의 char 1025145 위치를 보면 약 1MB 지점이다. 즉 요청 본문이 이미 상당히 커진 상태이고, 그 안 어딘가에 깨진 바이트가 들어가 있다는 뜻이다.
흔한 발생 경로
실제로 겪어보면 대부분 다음 셋 중 하나다.
- 파일을 읽다가 멀티바이트 문자가 잘린 경우 — 큰 파일을 부분적으로 읽거나, 이미 인코딩이 깨진 파일을 컨텍스트로 넣었을 때
- 터미널 출력·로그·바이너리 데이터가 컨텍스트로 들어간 경우 — 빌드 로그나 바이너리 파일을
cat한 결과가 그대로 대화에 쌓였을 때 - 클립보드 붙여넣기 과정에서 문자가 깨진 경우 — 다른 앱에서 복사해온 텍스트에 잘린 이모지가 섞여 있을 때
한 번 깨진 문자가 컨텍스트에 들어가면, 이후 모든 요청에 그 컨텍스트가 같이 실려 나가기 때문에 무슨 명령을 넣어도 같은 오류가 반복된다.
해결 방법
1. 가장 빠른 방법 — 세션 초기화
/clear
대화 컨텍스트에 쌓인 깨진 문자가 원인이라면 이걸로 끝난다. 작업 중이던 내용은 날아가지만, 어차피 그 상태로는 아무 요청도 안 나가므로 손해 볼 게 없다.
2. 특정 파일이 의심될 때 — 서로게이트 문자 찾기
특정 파일을 읽은 직후에 오류가 났다면, 그 파일 안에 깨진 문자가 있는지 확인한다.
bash
python3 -c "
data = open('의심파일', encoding='utf-8', errors='surrogatepass').read()
for i, c in enumerate(data):
if 0xD800 <= ord(c) <= 0xDFFF:
print(f'Surrogate at {i}: U+{ord(c):04X}')
"
출력이 있으면 그 위치의 문자를 지우거나, 파일을 UTF-8로 다시 저장하면 된다. file 명령이나 에디터의 인코딩 표시로 파일 전체가 깨져 있는지도 같이 확인해두는 게 좋다.
3. 반복된다면 — Claude Code 업데이트
bash
claude update
또는 npm으로 재설치한다. 직렬화 단계의 버그로 이런 케이스가 생겼다가 패치된 이력이 있어서, 같은 상황이 자꾸 반복되면 버전부터 올리는 게 맞다.
예방 팁
- 바이너리나 대용량 로그를 컨텍스트로 넣지 않는다. 꼭 봐야 하면
head,grep으로 필요한 부분만 잘라서 넣는다. - 외부에서 복사해온 긴 텍스트는 붙여넣기 전에 이모지·특수문자를 한 번 정리한다.
- 세션이 오래 길어지면 주기적으로
/clear하고 필요한 컨텍스트만 다시 넣는 습관이 이 오류뿐 아니라 응답 품질에도 도움이 된다.
정리
| 항목 | 내용 |
|---|---|
| 오류 | 400 The request body is not valid JSON: no low surrogate in string |
| 원인 | 요청 JSON 안에 짝이 없는 high surrogate 문자 존재 |
| 1차 해결 | /clear로 세션 초기화 |
| 2차 해결 | 의심 파일의 서로게이트 문자 제거 및 UTF-8 재저장 |
| 반복 시 | claude update |