400 Bad Request invalid JSON: 원인과 해결법
JSON이 유효하지 않다는 400 Bad Request는 요청 본문이 파싱되지 않았다는 뜻입니다. 셸 따옴표, 작은따옴표, 후행 쉼표, 직렬화하지 않은 객체를 확인하세요.

JSON이 유효하지 않다는 400 Bad Request는 서버가 요청 본문을 JSON으로 파싱하지 못했다는 뜻이므로, 서버는 필드를 검사하는 단계까지 가지도 못했습니다. 본문을 어떻게 만들었는지 살펴보세요. 셸 따옴표 처리가 본문을 망가뜨렸거나, 작은따옴표나 후행 쉼표가 있거나, 객체를 직렬화하지 않았거나, 빈 본문에 Content-Type: application/json을 붙인 경우입니다.
JSON 규칙은 RFC 8259와 MDN의 JSON.parse 오류 페이지에서, curl의 동작은 curl의 man 페이지와 everything curl에서 인용했습니다. 모두 2026-09-28에 확인했습니다. Sume의 응답은 현재 API 코드와 오류와 요청 한도 (영문) 문서에서 읽었습니다.
어떤 요청 본문이 유효하지 않은 JSON이 되나요?
JSON 파서가 거부하는 본문이라면 무엇이든 그렇습니다. RFC 9110은 400을, 잘못된 요청 구문처럼 클라이언트 오류로 보이는 문제 때문에 서버가 처리하지 않는 요청으로 정의합니다. JSON에 대해 RFC 8259는 문자열이 따옴표, 즉 " 문자로 시작하고 끝나며 모든 속성 이름은 문자열이라고 말합니다. MDN은 여기에 더해 JSON.parse()가 후행 쉼표나 01 같은 선행 제로를 허용하지 않는다고 설명합니다. 이런 본문 네 가지를 서버가 받는 그대로 적으면 다음과 같습니다.
| 서버가 받은 본문 | 실패 이유 | 해결 방법 |
|---|---|---|
{'prompt': 'hi'} | 작은따옴표로는 JSON 문자열이나 속성 이름을 감쌀 수 없습니다. | 큰따옴표를 쓰거나, 본문은 JSON 라이브러리가 만들게 하세요. |
{"prompt": "hi",} | 마지막 멤버 뒤에 후행 쉼표가 있습니다. | 쉼표를 지우세요. |
[object Object] | fetch에 본문으로 넘긴 객체가 toString()으로 변환됩니다. | JSON.stringify(body)를 보내세요. |
| 아무것도 없음 | application/json으로 표시한 빈 본문입니다. | 본문을 보내거나 헤더를 빼세요. |
Windows에서 curl로 보낸 JSON은 왜 실패하나요?
대개 셸 따옴표 처리 때문입니다. everything curl의 JSON 예시는 본문을 -d '{ "name": "Darth" }'처럼 작은따옴표로 감싸고, Windows에서는 작은따옴표가 같은 방식으로 동작하지 않는다고 설명합니다. Sume 문서도 같은 Unix 형태를 씁니다. PowerShell에서는 curl을 입력하면 다른 도구의 별칭이 실행될 수도 있으므로 curl.exe를 입력하거나, PowerShell Invoke-RestMethod로 JSON POST 요청하기를 참고하세요.
어느 환경에서나 통하는 해결책은 JSON을 파일에 두는 것입니다. 그러면 따옴표를 따로 처리할 필요가 없습니다. -d @file은 파일에서 본문을 읽지만 캐리지 리턴과 줄바꿈을 제거합니다. curl 7.82.0 이상의 --json @file은 파일을 그대로 POST하고 Content-Type: application/json과 Accept: application/json을 설정합니다. curl은 데이터가 JSON인지 검사하지 않으므로 파일은 여전히 유효한 JSON이어야 합니다. 명령의 나머지 부분은 여전히 사용하는 셸의 규칙을 따르며, 아래 명령은 Bash 기준으로 작성했습니다.
# body.json: {"model": "sume/auto", "prompt": "A red fox running through fresh snow"}
curl https://api.sume.com/v1/videos \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Idempotency-Key: fox-video-001" \
--json @body.jsonJSON이 아닌 본문에 Sume는 무엇을 반환하나요?
Sume 문서는 400 아래에 invalid_request와 bad_request를 모두 나열합니다. 현재 코드에서 파싱되지 않는 본문은 bad_request 쪽입니다. 이 오류는 파서가 낸 메시지를 그대로 담고 retryable: false, next_action: fix_input으로 표시되므로, 같은 바이트를 다시 보내도 소용없습니다.
JSON 헤더와 함께 보낸 빈 본문에는 대신 Body cannot be empty when content-type is set to 'application/json' 메시지가 돌아옵니다. 형식이 잘못된 본문에 대한 응답은 다음과 같습니다(일부 생략).
{
"error": {
"code": "bad_request",
"message": "Body is not valid JSON but content-type is set to 'application/json'",
"retryable": false,
"next_action": "fix_input"
}
}JSON은 파싱되는데 여전히 400이 나오면 어떻게 하나요?
그렇다면 대개 필드가 문제입니다. 필드가 라우트의 요청 스키마를 어기면, 현재 코드는 400 invalid_request와 함께 details.errors[] 항목을 돌려주며, 각 항목에는 path, message, type이 들어 있습니다. Format 실행 생성에서 알 수 없는 최상위 필드는 400 unknown_parameter이며, 이름이 비슷하면 제안이 함께 옵니다(webook_url → webhook_url).
API는 본문보다 키를 먼저 확인합니다. 현재 코드에서 잘못된 키와 망가진 본문을 함께 보내면 400이 아니라 401이 돌아오므로, 401부터 고치세요. 잘못된 Content-Type은 별개의 오류인 415 Unsupported Media Type 오류이고, POST /v1/videos의 필드 오류는 영상 생성 API 400 오류에서 다룹니다.
본문이 없는 POST에서 왜 유효하지 않은 JSON 오류가 나나요?
요청에 여전히 Content-Type: application/json이 붙어 있었기 때문입니다. 현재 코드에서는 이 헤더가 있으면 항상 JSON 파서가 실행되고, 빈 본문은 파싱에 실패합니다. Sume Job 취소처럼 본문을 받지 않는 POST에서는, 문서의 예시처럼 이 헤더를 빼세요.
curl -X POST https://api.sume.com/v1/jobs/job_123/cancel \
-H "Authorization: Bearer $SUME_API_KEY"출처
- RFC 9110: HTTP 시맨틱 (2026-09-28 확인)
- RFC 8259: JSON 데이터 교환 형식 (2026-09-28 확인)
- MDN: SyntaxError: JSON.parse: bad parsing (2026-09-28 확인)
- MDN: Fetch API 사용하기 (2026-09-28 확인)
- MDN: Object.prototype.toString() (2026-09-28 확인)
- curl man 페이지 (2026-09-28 확인)
- everything curl: 옵션의 인수 (2026-09-28 확인)
- everything curl: 차이점 (2026-09-28 확인)
- 오류와 요청 한도 (영문)
- Format 호출하기 (영문)
- Generation admission
- 영상 생성 (영문)
관련 글
개발자 카테고리의 다른 글
- 401 vs 403 vs 404 차이: API 오류별 의미
401은 자격 증명이 없거나 유효하지 않다는 뜻, 403은 자격 증명으로는 부족하다는 뜻, 404는 리소스가 없거나 숨겨졌다는 뜻입니다. 각각 고치는 법을 알아보세요.
- 429 vs 503 차이: 요청 한도인가요, 서버 과부하인가요?
429는 정해진 시간 동안 요청을 너무 많이 보냈다는 뜻이고, 503은 서버가 지금 요청을 처리할 수 없다는 뜻입니다. 둘 다 Retry-After를 담을 수 있습니다. 대응 방법을 알아보세요.
- API가 404 Not Found를 반환하는 이유와 해결법
API는 경로나 메서드에 맞는 라우트가 없을 때, 또는 보낸 자격 증명으로는 그 ID가 없을 때 404를 반환합니다. 둘을 구별하고 각각 고치는 법을 알아보세요.
- Bearer 토큰과 API 키의 차이는 무엇인가요?
API 키는 자격 증명의 한 종류이고, Bearer는 Authorization 헤더에 자격 증명을 담아 보내는 방식입니다. OAuth 토큰처럼 API 키도 bearer 토큰으로 보낼 수 있습니다.
작성자 Sume