Fix 'Unexpected End of JSON Input' — How to Repair Truncated JSON
Getting 'Unexpected end of JSON input'? Learn every cause — truncated responses, missing brackets, empty strings, LLM cutoffs — and fix it instantly in JavaScript, Python, and more.
Have broken JSON right now? Fix it free in under 1 second — no signup.
Fix My JSON →SyntaxError: Unexpected end of JSON input is one of the most common JSON errors in modern development — and one of the most confusing. The error message tells you _where_ the parser gave up, but not _why_ the JSON was cut short. This guide covers every cause, how to diagnose which one you're dealing with, and how to fix it — including a one-click repair for truncated JSON.
What Does "Unexpected End of JSON Input" Mean?
When JavaScript's JSON.parse() reads a string, it expects every opening bracket or brace to have a matching close, every string to have a closing quote, and the document to end cleanly. "Unexpected end of JSON input" means the parser reached the end of the string before it found what it was looking for.
JSON.parse('{"name": "Alice"')
// SyntaxError: Unexpected end of JSON input
The string {"name": "Alice" opens an object with { but never closes it with }. The parser hits the end of the string while still expecting more input — hence "unexpected end."
It's not a type error or a logic error. It's a structural error: the JSON is physically incomplete.
5 Causes of Unexpected End of JSON Input
1. Missing Closing Bracket or Brace
The most obvious cause. An object or array was opened but never closed.
// Missing closing }
JSON.parse('{"user": {"name": "Alice", "age": 30}')
// Missing closing ]
JSON.parse('["one", "two", "three"')
This happens when JSON is written by hand or assembled by string concatenation without proper termination. It also happens frequently when editing JSON config files — delete the wrong line and you lose a closing brace without realizing it.
2. Truncated API or Network Response
Your server (or a third-party API) returned a partial response. The response was cut off before it finished sending.
Common triggers:
- Incorrect
Content-Lengthheader — the client stops reading early - Proxy or CDN timeout — the middle layer drops the connection
- Server crash mid-stream — the process died while writing the response body
- Streaming response read incorrectly — a stream was consumed before it finished
When this happens, JSON.parse() receives the truncated string and fails.
// What you got (truncated mid-object)
const rawResponse = '{"results": [{"id": 1, "name": "Item A"}, {"id": 2, "name": '
JSON.parse(rawResponse)
// SyntaxError: Unexpected end of JSON input
Diagnostic step: Log the raw response body and its byte length before parsing. If the length is suspiciously low or ends mid-value, the response was cut.
3. LLM Response Hitting Token Limit
This is the most common cause in AI-powered applications in 2026. When you ask a language model (ChatGPT, Claude, Gemini) to output JSON, the model generates tokens until it hits max_tokens — and then stops, mid-sentence if necessary.
import json
What Claude or GPT returned when max_tokens was too low
llm_output = '{"summary": "This product is a great choice for developers who need", "score": 8, "tags": ["developer'
json.loads(llm_output)
json.decoder.JSONDecodeError: Unexpected end of data: line 1 column 102 (char 101)
The fix: increase max_tokens to give the model enough room to close all its brackets and quotes. As a rough guide, budget 1.5× the token count you expect the output to need. For structured JSON with nested objects, budget even more.
If you can't increase max_tokens, use a JSON repair library (see the repair section below) to recover what the model did return.
4. Empty or Null Response Body
JSON.parse("") throws immediately — an empty string is not valid JSON. This happens when:
- An API endpoint returns a 200 with no body (should have returned a 204)
- A fetch request reads the body twice (the stream is exhausted on the first
.json()call) - A caching layer returns an empty cache entry
// Empty string
JSON.parse("")
// SyntaxError: Unexpected end of JSON input
// Null or undefined coerced to string
JSON.parse(null)
// SyntaxError: Unexpected token n in JSON at position 0
Always check that the response body is non-empty before parsing:
async function safeFetch(url) {
const res = await fetch(url)
const text = await res.text()
if (!text || !text.trim()) {
throw new Error(Empty response from ${url})
}
return JSON.parse(text)
}
5. Unterminated String Value
A string value in the JSON was opened with " but the closing " was never written. This happens when a string value contains an unescaped newline or when the JSON was generated by concatenating strings without escaping special characters.
// Unescaped newline inside string
JSON.parse('{"message": "Hello\nWorld"}')
// SyntaxError: Unexpected token n in JSON at position 12
// (The parser sees the newline before the closing quote)
// Unterminated string at end of file
JSON.parse('{"message": "Hello')
// SyntaxError: Unexpected end of JSON input
The fix is to ensure strings are properly escaped. Newlines must be \n, carriage returns must be \r, and backslashes must be \\.
How to Fix the Error Manually
Step 1: Find What's Missing
Look at the last few characters of your JSON string. The missing piece is almost always one of:
- A closing
}for an object - A closing
]for an array - A closing
"for a string - Multiple nested closers at the end (e.g.,
}]}to close a nested structure)
// Broken
'{"users": [{"name": "Alice"}'
// What's missing: the ] to close the array and the } to close the root object
// Fixed
'{"users": [{"name": "Alice"}]}'
Step 2: Validate After Fixing
Use a JSON validator to confirm your fix is complete. Truncated JSON often has multiple layers of unclosed structures — fixing one bracket reveals another error deeper in the string.
Step 3: Fix the Root Cause
Don't just patch the output — find where the truncation happened:
- If it's a network response: add server-side logging to record full response bodies before they're sent
- If it's LLM output: increase
max_tokensor add a retry with a prompt asking the model to complete its JSON - If it's a hand-edited file: use a JSON-aware editor (VS Code, IntelliJ) that shows bracket matching
Fix Truncated JSON Automatically
Manually closing brackets works for simple cases, but deeply nested structures with multiple unclosed levels are hard to repair by eye. AI JSONMedic handles this automatically — paste your truncated JSON and the repair engine will:
- Walk the structure to find all unclosed brackets, braces, and strings
- Close them in the correct order
- Return valid JSON that
JSON.parse()accepts
This is especially useful for LLM output that was cut off mid-generation — the model's intent is usually clear from what it _did_ write, and the repair engine can complete the structure.
You can also use the [json-repair](https://pypi.org/project/json-repair/) Python library directly in your code:
from json_repair import repair_json
truncated = '{"name": "Alice", "tags": ["python", "json'
repaired = repair_json(truncated)
print(repaired)
{"name": "Alice", "tags": ["python", "json"]}
import json
data = json.loads(repaired)
For JavaScript/Node.js, wrap your parse in a try/catch and implement a basic bracket-completion fallback:
function parseOrRepair(jsonString) {
try {
return JSON.parse(jsonString)
} catch (e) {
if (e.message.includes('Unexpected end of JSON input')) {
// Count unclosed brackets and braces
let opens = 0
let openBraces = 0
let inString = false
let escaped = false
for (const char of jsonString) {
if (escaped) { escaped = false; continue }
if (char === '\\') { escaped = true; continue }
if (char === '"') { inString = !inString; continue }
if (inString) continue
if (char === '[') opens++
if (char === ']') opens--
if (char === '{') openBraces++
if (char === '}') openBraces--
}
// Append missing closers
let repaired = jsonString.trimEnd()
if (inString) repaired += '"'
repaired += ']'.repeat(Math.max(0, opens))
repaired += '}'.repeat(Math.max(0, openBraces))
return JSON.parse(repaired)
}
throw e
}
}
For production use, prefer a battle-tested library over a custom implementation. See the best JSON repair tools comparison for a full breakdown of options.
Language-Specific Notes
Python
Python's error message for the same problem is json.decoder.JSONDecodeError: Unexpected end of data:
import json
json.loads('{"name": "Alice"')
json.decoder.JSONDecodeError: Unexpected end of data: line 1 column 17 (char 16)
The char 16 position tells you where the parser stopped. Count characters from the start of your string to find where the truncation happened.
Node.js / TypeScript
In Node.js 18+ and modern browsers, the error message includes more context:
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
TypeScript doesn't add JSON parsing logic on top of JavaScript — JSON.parse() returns any, and the same runtime error applies. If you're using zod or similar for validation, validation errors are separate from parse errors.
Fetch API (Browser)
A common mistake with the Fetch API is calling .json() and .text() both — the body stream can only be consumed once:
// WRONG — stream consumed twice
const res = await fetch(url)
const text = await res.text() // consumes the stream
const data = await res.json() // throws — stream already read
// RIGHT — read text first, then parse manually
const res = await fetch(url)
const text = await res.text()
const data = JSON.parse(text) // you control error handling here
Preventing the Error Going Forward
For API responses:- Log the raw response body whenever
JSON.parse()throws — you need to see what was actually returned - Set explicit timeouts and handle them separately from parse errors
- Validate
Content-Type: application/jsonbefore parsing
- Use structured output / function calling when the API supports it — this constrains token generation to valid JSON
- Set
max_tokensgenerously (1.5–2× your expected output size) - Add a retry loop: if parsing fails, send the failed output back to the model with a prompt to complete it
- Use a JSON-aware editor with bracket highlighting
- Add a CI check:
node -e "JSON.parse(require('fs').readFileSync('config.json','utf8'))"to catch invalid config before deploy - Consider JSONC or JSON5 for config files if you want comments — use a parser that supports them rather than patching
JSON.parse()
For a broader overview of all JSON error types and how to fix them, see Fix Invalid JSON: Every Error Type. For validation best practices, the JSON Glossary covers the terminology you'll encounter in error messages and docs.
FAQ
What exactly does "unexpected end of JSON input" mean?
It means the JSON parser reached the end of the string before it could finish building a complete data structure. Some bracket, brace, or quote was opened but never closed. The parser was expecting more characters and instead hit the end of input.
Why does this error happen with fetch() and JSON APIs?
Two common reasons: (1) the response body is empty — the server returned 200 with no content, which res.json() will fail to parse; (2) the response body is truncated due to a network timeout, proxy cutoff, or incorrect Content-Length header. Log the raw response text before parsing to diagnose which one you're dealing with.
Why do LLMs return truncated JSON?
Because max_tokens was set too low. Language models generate output one token at a time and stop when they hit the limit — regardless of whether the structure is complete. Increase max_tokens or use structured output mode (OpenAI's response_format: {type: "json_object"}, or equivalent from other providers) to prevent mid-structure cutoffs.
Can I fix truncated JSON without losing data?
Yes — the repair tools close the structure at the point of truncation, preserving all data that was written before the cutoff. If a string was mid-way through, the repair will close it at the current position. If you were in a nested object several levels deep, each level will be closed in the correct order. You don't lose the data that was successfully generated — only the data that never made it into the response.
Does JSON.parse() tell me which character caused the error?
For "unexpected end of JSON input" specifically, no — it just tells you the parser ran out of input. You can find the truncation point by looking at the last few characters of your string. For other parse errors (like Unexpected token), the error message includes a character position.
What's the fastest way to fix truncated JSON online?
Paste it into the AI JSONMedic repair tool — it automatically closes unclosed brackets and strings, returns the repaired JSON, and shows you exactly what was added. For programmatic repair, use the json-repair Python library or the equivalent for your language.
Still dealing with broken JSON?
Paste it in and get it fixed in under 1 second — free, no signup, no install. Works with ChatGPT, Claude, n8n, and any AI output.
Fix My JSON Free →Related Articles