SyntaxError: Unexpected end of JSON input

Node.js · updated 2026-11-04

Thrown by JSON.parse() and by fetch's response.json() when the text ends before the JSON is complete. An empty string gives exactly this message; a body cut off midway gives it too.

SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at parseJSONFromBytes (node:internal/deps/undici/undici:5584:19)
    at successSteps (node:internal/deps/undici/undici:5555:27)
    at async getOrder (file:///app/src/api.js:11:16)

Quick fix

Read the response as text first and check the status and length. If the body is empty (a 204, a 401 or 500 with no body, a HEAD request), handle that case instead of parsing. If it is cut off, look at timeouts or proxies between you and the server.

  1. Log res.status and the raw text with await res.text() before parsing.
  2. Treat 204 No Content and empty bodies as "no data" instead of calling res.json().
  3. Check res.ok first: many error responses have an empty body or HTML, not JSON.
  4. For files, make sure the write finished before another process reads it (write to a temp file, then rename).
  5. Wrap JSON.parse of external data in try/catch and log the first part of the text.
typescript
async function readJson<T>(res: Response): Promise<T | null> {
  const text = await res.text();
  if (!res.ok) throw new Error(`HTTP ${res.status}: ${text.slice(0, 200)}`);
  if (!text.trim()) return null;            // 204 or empty body
  try {
    return JSON.parse(text) as T;
  } catch {
    throw new Error(`Invalid JSON (${text.length} bytes): ${text.slice(0, 200)}`);
  }
}

Why it happens

An empty response body

A 204 No Content, a DELETE that returns nothing, or an error status with an empty body all give an empty string, and parsing "" throws this error.

Parsing an error response

A 401, 404 or 502 from a gateway often has no body or a non-JSON one. Code that calls res.json() without checking res.ok fails here instead of reporting the real status.

A truncated body

A proxy timeout, a dropped connection or a server crash mid-response leaves half a JSON document. The error appears intermittently and usually on larger responses.

Reading a file while it is being written

A JSON cache or config file read at the same moment another process writes it can be empty or partial. Writes that truncate first make this more likely.

Other fixes

  • In Express, only call express.json() parsing on routes that expect a body, and send a 400 for empty ones.
  • For streaming APIs, parse each complete line (NDJSON) instead of the whole body at once.

Same error, other wording

  • SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>)
  • SyntaxError: Expected property name or '}' in JSON at position 1
  • SyntaxError: Unterminated string in JSON at position 4096

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the 'Unexpected end of JSON input' errors in production, show me the request, status and body length for each, and make the calling code check status and empty bodies before parsing.

Plans from $29/moSee what your agent readsSee the setupCancel any time from the billing portal

Related errors

More in JSON, parsing and validation

References: MDN: JSON.parse() errors, MDN: Response.json()