Common causes
1. Calling res.json() on an empty response
A 204 No Content reply, a HEAD request or an error handler that sends no body gives response.json() an empty string to parse. Read the body as text first and only parse it when there is something there.
const res = await fetch('/api/session', { method: 'DELETE' });
const data = await res.json();const res = await fetch('/api/session', { method: 'DELETE' });
const text = await res.text();
const data = text ? JSON.parse(text) : null;2. Parsing an unset variable or storage key
JSON.parse("") throws this error. Environment variables, cookies and form fields that exist but are empty all produce an empty string, so give the parser a default.
const flags = JSON.parse(process.env.FEATURE_FLAGS);const flags = JSON.parse(process.env.FEATURE_FLAGS || '{}');3. A truncated payload
Logs, database columns with a length limit, terminal scrollback and chat tools often cut long JSON. The text simply stops, leaving arrays and objects open. Get the complete payload again; if that is impossible, Fix it closes the brackets so you can read what survived.
{"page": 3, "results": [{"id": 581}, {"id": 582},{"page": 3, "results": [{"id": 581}, {"id": 582}]}4. Parsing a stream chunk by chunk
A Node.js data event delivers part of a body, not a complete document. Calling JSON.parse on each chunk fails on the first one that ends mid-value. Collect every chunk and parse once at the end.
req.on('data', (chunk) => {
const body = JSON.parse(chunk);
handle(body);
});let raw = '';
req.on('data', (chunk) => (raw += chunk));
req.on('end', () => handle(JSON.parse(raw)));5. A closing bracket deleted while editing
Removing the last block of a hand-edited file can take the final } or ] with it. The parser only notices at the end of the file, so the error points to the last line even though the bracket belongs further up.
{"server": {"port": 8080, "host": "0.0.0.0"}{"server": {"port": 8080, "host": "0.0.0.0"}}Frequently asked questions
Why does the error point to the last line of my file?
The parser cannot know a bracket is missing until the text ends, so the position is always the end of the input. PasteKit also reports the line where the still-open bracket started, which is usually where you need to look.
Is an empty string valid JSON?
No. Valid JSON must contain exactly one value, and the smallest documents are things like {}, [], “” or 0. An empty body has to be handled before you call JSON.parse.
How do I tell an empty body from a truncated one?
Log the length of the raw text. A length of 0 means the server sent nothing, so check the status code; a long text that stops mid-object means something cut it, such as a proxy limit, a log line limit or a dropped connection.