← Todos os artigos

Unexpected Token o em JSON na posição 1: causas e correção

Esse «o» minúsculo é o segundo caractere de «[object Object]». Você passou um objeto JavaScript para JSON.parse() em vez de uma string. Aqui cada variação desse erro e a correção em uma linha para cada.

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 1

A 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ê passouEm que o JS o converteToken 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álidosem 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 0

Correçã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ê quer mod.default, não mod.
  • [object AsyncFunction] — passar a referência de uma função assíncrona em vez de chamá-la: serialize fn() (o valor resolvido da promise), não fn.
  • [object HTMLDocument] — passar document por engano (por exemplo, de um snippet antigo do debugger).
  • [object FormData] — usar fetch(url, { body: formData }) está OK, mas JSON.parse(formData) não está — converta antes com Object.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 async antes 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 com response.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.