Dev.to WebDev πŸ›  Dev πŸ‘ 0 πŸ“– 4 min read

Stop counting characters to find a JSON error

It is late and the deploy is red. The log has one line in it: 362 characters of JSON, no line breaks, and this. Expected ',' or ']' after array element in JSON at position 218 (line 1 column 219) Position 218. S

Stop counting characters to find a JSON error

It is late and the deploy is red. The log has one line in it: 362 characters of JSON, no line breaks, and this.

Expected ',' or ']' after array element in JSON at position 218 (line 1 column 219)

Position 218. So you find an editor that shows the column number, paste the line in, and move the cursor along until it says 219. Then you look at the characters around it and guess what is wrong.

Somewhere in that line is one missing comma. JSON.parse found it straight away. It just gave you a number instead of showing you.

Find it yourself first

Here is the line. Try to spot the mistake before you read on.

{"page":1,"per_page":3,"total":42,"data":[{"id":101,"name":"Ada Lovelace","email":"[email protected]","roles":["admin","editor"],"active":true},{"id":102,"name":"Alan Turing","email":"[email protected]","roles":["editor" "viewer"],"active":false},{"id":103,"name":"Grace Hopper","email":"[email protected]","roles":["viewer"],"active":true}],"next":"/users?page=2"}

Now paste this into your browser console and see what your browser tells you:

const text =
  '{"page":1,"per_page":3,"total":42,"data":[{"id":101,"name":"Ada Lovelace","email":"[email protected]","roles":["admin","editor"],"active":true},{"id":102,"name":"Alan Turing","email":"[email protected]","roles":["editor" "viewer"],"active":false},{"id":103,"name":"Grace Hopper","email":"[email protected]","roles":["viewer"],"active":true}],"next":"/users?page=2"}';
try {
  JSON.parse(text);
} catch (e) {
  console.log(e.message);
}

Chrome 145:

Expected ',' or ']' after array element in JSON at position 218 (line 1 column 219)

Firefox 146:

JSON.parse: expected ',' or ']' after array element at line 1 column 219 of the JSON data

Safari (WebKit 26):

JSON Parse error: Expected ']'

Chrome and Firefox give you a count. "Line 1" is no help when there is only one line. Safari gives you less. It says it expected a ], and nothing about where.

Make the console count

If the text is already in a variable, the console can count for you:

text.slice(200, 240);
// '"roles":["editor" "viewer"],"active":fal'

Character 218 is the quote that opens "viewer". There is no comma after "editor".

But at that hour the text is not in a variable. It is in a log, a ticket or a chat message. And the usual way to pretty-print it, JSON.stringify(JSON.parse(text), null, 2), fails with the same message. It has to parse first, and parsing is the part that is broken.

Stop counting. Format it anyway.

Broken JSON can still be formatted. Change nothing but spaces and line breaks outside strings, and the parser's line number points at something you can read.

The Express Lint validator does this when you press Validate & Format on JSON that will not parse. Same line:

The one-line JSON is pasted, Validate & Format is pressed, and the text is formatted over 36 lines with line 21 marked

The message now says line 21 column 18. Line 21 has a red bar. The quote the parser stopped on has a box round it:

      "roles":[
        "editor" "viewer"
      ],

Two values. No comma. Every other value sits on its own line, so this one is impossible to miss. One click, instead of 218 characters of counting.

Nothing else changed. The strings are exactly as you pasted them, and Ctrl+Z gives you back the one line, character for character.

When the message blames the wrong thing

Here is another line from a log. Copy it and try it yourself.

{"order":5821,"status":"shipped","items":[{"sku":"BK-101","title":"Notes on the Analytical Engine","qty":1,"price":12.5},{"sku":"BK-204","title":"Computing Machinery and Intelligence","qty":2,"price":9.99,},{"sku":"BK-310","title":"COBOL at Sixty","qty":1,"price":15}],"total":47.48}

Chrome 145:

Expected double-quoted property name in JSON at position 205 (line 1 column 206)

Firefox 146:

JSON.parse: expected double-quoted property name at line 1 column 206 of the JSON data

Safari (WebKit 26):

JSON Parse error: Property name must be a string literal

All three ask for a property name. Nothing is missing a name. The mistake is one character earlier: a comma after 9.99, with nothing after it.

Formatted, it is plain:

The order JSON formatted over 25 lines, line 15 ending in a comma and the closing brace on line 16 boxed

      "price":9.99,
    },

Line 15 ends with a comma. Line 16 closes the object. After a comma the parser expects another name, finds }, and stops there: line 16, column 5.

The one thing it will not do: guess

Formatting broken JSON has one real danger. A line break inside a string changes your data. So every quoted string is copied as written.

That needs the quotes to pair up. When they do not, nobody can say for sure where a string ends. Then the validator leaves your text exactly as it is, on one line, and only marks where the parser stopped. A wrong guess there would move text in or out of a string.

Repair, only when you ask

Repair is off unless you turn it on. After a failed check there is a Try repair button. It runs jsonrepair, an open source library, in your browser. No AI. No server.

On the first example it adds the missing comma. On the second it removes the trailing comma. Both come back as valid, formatted JSON.

When the quotes do not pair up, repair has to guess where a string ends. Read the result before you keep it.

Then see its shape

Once it parses, Open in viewer takes it to the JSON viewer in the same tab. It opens as a graph, and one click turns it into a tree. Expand all opens every level. Here is the repaired order:

The repaired order JSON as a graph: order, status, items and total, with each of the three items opened to sku, title, qty and price

The JSON stays in the tab on the way. Nothing is uploaded.

In short

Position 218 is a count, not a place. On one line it is all you get, and Safari does not even give you that. Format the text without parsing it, and the error points at a line you can read.

Try it yourself: Express Lint

πŸ“° Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.