JSON errors

JavaScript, from JSON.parse() and localStorage

"[object Object]" is not valid JSON

JSON.parse only accepts a string. Give it an object and JavaScript first turns the object into the string "[object Object]", which isn't JSON. The value you're parsing is already parsed, or it was saved without JSON.stringify.

How each browser and language words it

Chrome, Edge and Node 20+
SyntaxError: "[object Object]" is not valid JSON
Older Chrome and Node 18 and below
SyntaxError: Unexpected token o in JSON at position 1
Firefox
SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data

Paste your JSON to find the exact line

This is the string JSON.parse actually received. There's no JSON in it to repair.

Skip to editor
Explorer
Open Files

No files open

0 files open

jsoneditor.io v2

[object Object]
JSONUTF-8
Spaces: 2

Causes and how to fix each one

1. Parsing data that is already an object

response.json(), axios's response.data and most HTTP clients already give you a parsed object. Calling JSON.parse on the result again throws this error, so use the value as it is.

JavaScript
const { data } = await axios.get('/api/orders')
// data is already an object, no JSON.parse needed
console.log(data.items.length)

2. Saving an object to localStorage without stringify

localStorage only stores strings, so setItem quietly saves "[object Object]" when you pass it an object. Reading it back then fails. Stringify on the way in and parse on the way out, and clear the bad value that was already saved.

JavaScript
localStorage.setItem('user', JSON.stringify(user))
const user = JSON.parse(localStorage.getItem('user') ?? 'null')

3. String concatenation with an object

Building a JSON string by hand with + or a template literal turns any object into [object Object]. Build the whole value as an object and call JSON.stringify once at the end.

Questions people ask

Why does the old message say "Unexpected token o"?

The text is [object Object]. The [ looks like the start of an array, then the parser hits the o of object at position 1 and gives up, which is where the older message came from.

How do I check if a value is already parsed?

typeof value === 'string' tells you whether it still needs parsing. If it's 'object', it has already been parsed and you can use it directly.

Tools for this