Bad control character in string literal in JSON

ErrorJavaScript

SyntaxError: Bad control character in string literal in JSON at position 32 (line 3 column 20)

Where it stops

  "id": 7,
  "note": "line one
line two"

What it means

A JSON string cannot hold a raw line break or tab. The parser reached one inside a string and stopped. The position is that character, so the fix is at the end of the line it names.

Last verified on Chromium 145, Firefox 146, WebKit 26 and Node 20.

The validator opens with the error marked. Examples travel in the URL fragment, which browsers never send to a server.

Express Lint lays broken JSON out by bracket depth and marks the line where it stops. It changes only spaces and line breaks outside strings. Strings in either quote stay as written. If the quotes do not pair up, it leaves your text as it is. Ctrl+Z undoes it. See how it works.

Usually
A line break inside a stringA tab you cannot seeText from a file or a databaseSafari says Unterminated string
Fix
Write the line break as \n and the tab as \t, as the fixed example does.

The fix

Write the line break as \n and the tab as \t, as the fixed example does. Better, let JSON.stringify build the string, because it escapes both for you.

broken.jsonFails to parse
{
  "id": 7,
  "note": "line one
line two"
}
JSON.parse stops at the line break at the end of line 3.

Line 3: add \n.

fixed.jsonParses
{
  "id": 7,
  "note": "line one\nline two"
}
JSON.parse reads it.

How the message appears

Chrome and Node first, then Firefox, then Safari. The next line is Chrome for a tab in a string. Node 20 leaves out the line and column.

Console
  • SyntaxError: Bad control character in string literal in JSON at position 32 (line 3 column 20)Chrome and Node
  • SyntaxError: JSON.parse: bad control character in string literal at line 3 column 20 of the JSON dataFirefox
  • SyntaxError: JSON Parse error: Unterminated stringSafari
  • SyntaxError: Bad control character in string literal in JSON at position 11 (line 1 column 12)
  • SyntaxError: Bad control character in string literal in JSON at position 32Older V8 wording

What causes it

  1. A line break inside a string

    Someone pressed Enter inside a quoted value, or text with several lines was written into the JSON as it is. JSON strings cannot span lines, so the parser stops at the break. In the example the string "line one is cut off by the line break, and line two" is left over on the next line.

  2. A tab you cannot see

    A tab looks like spaces. Text copied from a spreadsheet or a terminal can carry them. A tab inside a string gives the same message as a line break, and the position is the tab. If a string looks fine and still fails, look for a tab in it.

  3. Text from a file or a database

    Notes, addresses and comments often have line breaks in them. If you build the JSON by joining strings, those breaks go straight into the document. JSON.stringify writes each one as \n.

  4. Safari says Unterminated string

    Safari does not mention a control character. It says Unterminated string, even though the closing quote is there on the next line. Safari uses the same words when a string really is cut off at the end of the document.

Worth knowing

NoteJSON allows only a few backslash escapes. Bad escaped character lists them.

NotePython words this as Invalid control character at. See the Python page.

Your JSON and text are processed entirely in your browser and are never sent anywhere. To understand how the site is used we record each page view (the page, the referrer and an approximate location from your IP address) and keep it for 90 days. Nothing is stored on your device unless you choose it. Accept to also store a device identifier here and record your browser and device characteristics, which is what lets a return visit be told from a new one. Decline and nothing is sent at all. We respect Do Not Track. See our privacy policy.