SyntaxError: Unexpected token o in JSON at position 1 — esse o minúsculo é o segundo caractere de [object Object]. Significa que você passou um objeto JavaScript diretamente para JSON.parse() em vez de uma string JSON. Este artigo explica cada variante desse erro e como corrigir cada uma em menos de um minuto.
Por que o erro diz "token o"
Quando você passa um valor não-string para JSON.parse(), o JavaScript primeiro o converte forçadamente em string. Um objeto comum é convertido em "[object Object]". O parser vê [ na posição 0 (válido — início de um array), então o na posição 1 (inválido — não é um elemento válido de array). Daí: Unexpected token o at position 1.
JSON.parse({})
// Equivalente a: JSON.parse("[object Object]")
// SyntaxError: Unexpected token o in JSON at position 1A causa mais comum: não usar await em response.json()
Esta é a causa número um desse erro em bases de código reais. Um objeto Response do fetch() não é uma string — é um wrapper de ReadableStream. Passá-lo para JSON.parse() o converte em "[object Response]".
// ❌ Errado — response é um objeto Response, não uma string
const response = await fetch('/api/user');
const data = JSON.parse(response);
// SyntaxError: Unexpected token o in JSON at position 1
// ✓ Correto — deixe o navegador fazer o parse do stream como JSON
const data = await response.json(); Da mesma forma, se você chamar response.text() sem await, obtém um objeto Promise (que é convertido em "[object Promise]").
// ❌ await faltando — text é uma Promise, não uma string
const text = response.text();
const data = JSON.parse(text);
// SyntaxError: Unexpected token o in JSON at position 1
// ✓ Correto
const text = await response.text();
const data = JSON.parse(text);Outros objetos que disparam este erro
| O que você passou | Em que o JS o converte | Token do erro |
|---|---|---|
{} ou qualquer objeto comum | "[object Object]" | token o na posição 1 |
undefined | "undefined" | token u na posição 0 |
true / false | "true" / "false" — na verdade JSON válido! | sem erro |
Um objeto Response | "[object Response]" | token o na posição 1 |
Uma Promise | "[object Promise]" | token o na posição 1 |
null | "null" — JSON válido | sem erro (retorna null) |
Causa: passar um objeto em vez de serializá-lo
Um erro relacionado: tentar "fazer parse" de um objeto JavaScript que você já tem em memória. JSON.parse() recebe uma string; se você já tem um objeto, não precisa fazer parse.
const config = { host: 'localhost', port: 3000 };
// ❌ Sem sentido — config já é um objeto
const parsed = JSON.parse(config);
// ✓ Se você quer uma cópia profunda, use structuredClone ou stringify + parse
const clone = JSON.parse(JSON.stringify(config));
// ✓ Se quiser enviá-lo, use JSON.stringify
const body = JSON.stringify(config);Causa: Python ou outro backend retornando Content-Type errado
Às vezes o servidor retorna uma mensagem de erro em texto puro (como "ok" ou "not found") com status 200 e sem cabeçalho Content-Type. O frontend assume JSON, chama response.json() e recebe um erro de token inesperado porque o corpo não é JSON válido.
// O servidor envia a string literal: ok
// O navegador tenta fazer parse como JSON:
JSON.parse("ok")
// SyntaxError: Unexpected token o in JSON at position 0Correção: Sempre verifique response.ok e response.headers.get('Content-Type') antes de chamar response.json():
const response = await fetch('/api/action');
if (!response.ok) {
const text = await response.text(); // seguro — pode não ser JSON
throw new Error(`HTTP ${response.status}: ${text}`);
}
const data = await response.json();Variantes menos comuns de [object X]
Qualquer valor cujo toString() retorne uma string começando com [object dispara o mesmo erro na posição 1. Além de [object Object], os que realmente aparecem em código real:
[object Module]— passar o resultado de um import dinâmico:const mod = await import('./data.json', { with: { type: 'json' } }); você quermod.default, nãomod.[object AsyncFunction]— passar a referência de uma função assíncrona em vez de chamá-la: serializefn()(o valor resolvido da promise), nãofn.[object HTMLDocument]— passardocumentpor engano (por exemplo, de um snippet antigo do debugger).[object FormData]— usarfetch(url, { body: formData })está OK, masJSON.parse(formData)não está — converta antes comObject.fromEntries(formData).
Checklist rápido de correção
- fetch + JSON.parse? Substitua por
await response.json(). - Falta um await em algum lugar da cadeia? Toda chamada
asyncantes do parse precisa ser awaitada. - Já tem um objeto? Não precisa fazer parse — use diretamente ou clone com
structuredClone(). - Servidor retornando não-JSON em erro? Leia com
response.text(), não comresponse.json(), quando a resposta pode não ser JSON.
Perguntas frequentes
O que significa "Unexpected token o in JSON at position 1"?
Você passou um objeto JavaScript para JSON.parse(). O JavaScript converte o objeto na string "[object Object]"; o parser aceita [ na posição 0, mas rejeita o o na posição 1.
Como corrijo com fetch?
Não chame JSON.parse(response). Use await response.json(), que lê o stream de resposta e o parseia para você. Garanta que toda etapa da cadeia esteja awaitada.
Preciso de JSON.parse se já tenho um objeto?
Não. JSON.parse() só converte uma string JSON em um valor. Se você j á tem um objeto, use-o diretamente, ou faça cópia profunda com structuredClone() em vez de JSON.parse(JSON.stringify(obj)).
"Unexpected token o" é o mesmo que "[object Object] is not valid JSON"?
Compartilham a mesma causa raiz — um objeto convertido em string antes do parse. Builds mais novas do V8 imprimem o texto [object Object] is not valid JSON; as mais antigas imprimem Unexpected token o. Veja Corrigir "[object Object] is not valid JSON" para a análise completa.
Inspecione a resposta bruta
Se não sabe ao certo o que sua API está retornando, cole o corpo bruto em JSON Fix para validá-lo. Se não for JSON válido, o validador dirá exatamente o que está errado.
- JSON Fix — validar e reparar JSON no navegador
- Corrigir "[object Object] is not valid JSON" — o guia completo de erros de sintaxe JSON
- Unexpected end of JSON input — quando o parser fica sem dados antes da estrutura ser completada
- Lidando com JSON quebrado em JavaScript — padrões de parse seguro e recuperação de erros