What Does "Unexpected Non-Whitespace Character After JSON" Mean?
In JavaScript engines (Chrome V8, Node.js), calling JSON.parse() on a string containing extra characters after a valid JSON root throws:
SyntaxError: Unexpected non-whitespace character after JSON at position 15 (line 1 column 16)In Firefox / SpiderMonkey:
SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data at line 1 column 16In Python:
json.decoder.JSONDecodeError: Extra data: line 1 column 16 (char 15)This error means the JSON parser successfully parsed a complete, valid JSON value (like an object or array), but then found additional characters instead of reaching the end of the string.
Common Causes & Examples
Cause 1: Two JSON Objects Back-to-Back (NDJSON / JSON Lines)
When reading data from streaming APIs (like OpenAI ChatGPT stream, Docker logs, or Elasticsearch dumps), each line is an independent JSON object:
{"id": 1, "status": "ok"}{"id": 2, "status": "pending"}Passing this entire string to JSON.parse() fails at character position 26 (the second {).
Cause 2: Appended Log Messages or Server Output
If a backend script emits a debug statement before or after JSON output:
{"status": "success", "count": 4}Connected to database.The text Connected to database. sits after the valid closing brace }, causing an immediate parse error.
Cause 3: Duplicate API Payloads in Network Buffers
When reading raw TCP streams or improperly delimited HTTP chunks, two responses can concatenate into a single buffer.
How to Fix It
Fix 1: Parsing NDJSON / JSON Lines Properly
If your data consists of newline-delimited JSON, split the string by newlines and parse each line independently:
const rawNDJSON = '{"id": 1, "name": "Alpha"}\n{"id": 2, "name": "Beta"}';
// ✅ Split by line, filter empty lines, and parse each
const records = rawNDJSON
.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0)
.map(line => JSON.parse(line));
console.log(records);
// [{ id: 1, name: 'Alpha' }, { id: 2, name: 'Beta' }]To test and inspect newline-delimited payloads interactively, use the JSON Lines tool.
Fix 2: Extracting JSON from Messy Output with Regex
If server logs or trailing text are attached to your JSON payload:
function extractFirstJSON(str) {
const firstBrace = str.indexOf('{');
const lastBrace = str.lastIndexOf('}');
if (firstBrace !== -1 && lastBrace !== -1 && lastBrace > firstBrace) {
const cleanJSON = str.substring(firstBrace, lastBrace + 1);
return JSON.parse(cleanJSON);
}
throw new Error("No valid JSON object boundaries found in input");
}
// Example:
const messy = '{"user": "dev123", "token": "abc"} Execution time: 12ms';
const result = extractFirstJSON(messy);
console.log(result.user); // "dev123"Fix 3: Handling Python Extra Data with JSONDecoder.raw_decode
In Python, the JSONDecoder class provides raw_decode(), which returns the parsed object along with the character index where it stopped:
import json
raw_stream = '{"id": 101, "event": "click"} trailing text...'
decoder = json.JSONDecoder()
obj, end_pos = decoder.raw_decode(raw_stream)
print("Parsed object:", obj) # {'id': 101, 'event': 'click'}
print("Ended at character:", end_pos) # 29
print("Remaining text:", raw_stream[end_pos:]) # " trailing text..."Diagnostic Summary
| Symptom | Probable Cause | Recommended Action |
|---|---|---|
Multiple {...}{...} objects | Streaming or NDJSON input | Split by newlines or parse sequentially |
Text after final } | Server debugging logs | Clean output pipeline or extract bounded substring |
| Extra characters inside payload | Malformed JSON template | Inspect in JSON Validator |
Use JSONKit's JSON Fixer to automatically inspect and repair malformed strings directly in your browser.