Bad escaped character in JSON strings

Inside a JSON string a backslash may be followed by only these: ", \, /, b, f, n, r, t, or u followed by exactly four hex digits. Anything else is a bad escape. Separately, the raw control characters U+0000 to U+001F may never appear literally in a string: they have to be escaped.

How the message appears

The same fault, worded by different engines. V8 (Chrome, Node, Edge) changed its format around Chrome 109, so older and newer runtimes disagree about the same document.

  • SyntaxError: Bad escaped character in JSON at position 14
  • SyntaxError: JSON.parse: bad escaped character at line 1 column 15 of the JSON data
  • SyntaxError: Bad control character in string literal in JSON at position 12

The fix

Double every literal backslash and replace real newlines and tabs with \n and \t. A serializer does this correctly; hand-editing is where it goes wrong.

Fails to parse
{
  "path": "C:\Users\ada",
  "note": "line one
line two"
}
Parses
{
  "path": "C:\\Users\\ada",
  "note": "line one\nline two"
}

The example travels in the URL fragment, which browsers never send to a server.

What causes it

Windows file paths

"C:\Users\ada" contains \U and \a, neither of which is a valid escape. Each backslash has to be doubled: "C:\\Users\\ada".

A literal newline inside a string

Pressing Enter inside a quoted value is invalid, however readable it looks. Multi-line text must use \n; JSON strings cannot span lines.

Escaping a single quote

\' is a valid escape in JavaScript and Python and is not one in JSON. A single quote inside a JSON string needs no escape at all.

A truncated unicode escape

\u12 fails: \u requires exactly four hex digits. Characters outside the basic multilingual plane need a surrogate pair, so an emoji is two \uXXXX escapes, not one.

Worth knowing

  • Let JSON.stringify build strings that contain paths, regexes or user text. It escapes exactly what needs escaping and nothing else.
  • A tab pasted into a string value is invisible and produces "Bad control character in string literal". If a string looks fine but fails, check for a literal tab.

Written by Vishnu Shankar.

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.