Consulta de mensagens de erro JSON: do texto do erro direto para a correção
Resumo: Descubra a causa pela mensagem exata do JSON.parse: 12 erros frequentes no Chrome, Firefox e Safari, incluindo páginas de erro HTML, truncamento e análise dupla.

Resumo da ópera: quando aparecer um erro de JSON.parse, pegue primeiro a posição e o token; uma posição 0 significa verificar resposta HTML, BOM ou tipo errado, e uma mensagem "Expected" significa olhar o caractere anterior — não releia linha por linha a partir da posição informada.
O texto do erro não é ruído — é a resposta. O analisador diz qual caractere encontrou, o que esperava e o que recebeu de fato. Pesquisar pela mensagem de erro é melhor do que reescrever o documento inteiro à mão.
Todo erro de JSON.parse() tem três partes: a posição (um deslocamento de caractere, ou linha/coluna), a expectativa (Expected...) e a realidade (Unexpected token X, ou xxx não é JSON válido). As engines formulam de forma diferente — Chrome e Node (V8) dizem Expected ',' or '}' after property value in JSON at position 25, o Firefox diz JSON.parse: expected ',' or '}' after property value in object at line 3 column 1, o Safari diz JSON Parse error: Expected ',' or '}' — mas os três apontam para a mesma quebra de sintaxe. Ao consultar um erro, ignore as palavras e pegue os três fatos: qual caractere, o que era esperado, o que chegou.
1. A tabela de consulta dos 12 erros
A coluna da esquerda é o fragmento mais identificável do seu console (formulação do V8). As variantes de Firefox/Safari estão entre parênteses.
| Texto do erro (V8) | Causa real | Correção |
|---|---|---|
Unexpected token < in JSON at position 0 |
A API retornou HTML (página 404, template 500, redirecionamento de login, fallback de proxy), não JSON | Verifique primeiro response.status e Content-Type; não conserte o JSON |
Unexpected end of JSON input |
A entrada está vazia ou truncada: corpo vazio, 204, download interrompido, cópia sem a última linha | Trate o caso vazio, compare Content-Length para achar o corte |
Unexpected token o / "[object Object]" is not valid JSON |
Um objeto já analisado foi passado de novo ao JSON.parse() e convertido para string |
Verifique typeof; se for um objeto, use-o diretamente |
"undefined" is not valid JSON |
A variável nunca foi atribuída (JSON.parse(undefined)) |
Inicialize valores padrão; proteja antes de analisar |
Expected double-quoted property name in JSON |
Uma vírgula final ({"a": 1,}); o analisador espera outra chave e encontra } |
Remova a vírgula depois do último item |
Expected property name or '}' in JSON |
Uma chave sem aspas ou com aspas simples ({name: "Ada"}, {'name': 'Ada'}) |
Coloque aspas duplas em todas as chaves |
Expected ',' or '}' after property value in JSON |
Uma vírgula faltando ({"a": 1 "b": 2}) ou um comentário após um valor |
Adicione a vírgula; remova o comentário |
Unexpected token '/' |
Um comentário // ou /* */ dentro do JSON |
Remova-o, ou analise a configuração como JSONC |
Bad control character in string literal |
Uma quebra de linha crua, tabulação ou outro caractere de controle U+0000–U+001F dentro de uma string | Escreva \n; gere com JSON.stringify |
Unterminated string in JSON |
Uma string aberta com " que nunca foi fechada, ou uma aspa interna não escapada |
Escape as aspas internas como \" |
Unexpected non-whitespace character after JSON |
Dois documentos em um texto: {}{}, NDJSON, um wrapper JSONP |
Separe por linhas e analise cada uma, ou use um analisador NDJSON |
JSON.parse is not a function |
Sua própria variável está sombreando o JSON global |
Renomeie a variável; nunca a chame de JSON |
Os dois primeiros merecem uma olhada mais de perto, porque nenhum significa "seu JSON está errado" — eles significam "o que você recebeu não é o que você pensa que é".
2. Três origens comuns de erro na posição 0
Uma posição 0 significa que o primeiro caractere é ilegal. Se nada parecer suspeito, o caractere provavelmente é invisível. Três suspeitos de sempre:
Primeiro: <, significando HTML. Este é o erro de análise mais comum em produção. Uma URL errada, uma sessão expirada redirecionada pelo gateway ou um template de erro do servidor — o corpo começa com <!DOCTYPE html> e o analisador desiste no primeiro caractere. O movimento correto é abrir o painel Network e ler a resposta crua, depois corrigir a chamada da API, não o JSON.
Segundo: um BOM ou caracteres de largura zero. Arquivos salvos pelo Bloco de Notas do Windows frequentemente começam com um BOM UTF-8 (\uFEFF), e texto copiado de páginas web ou apps de mensagem pode carregar espaços de largura zero (\u200B–\u200D). Invisíveis para você, óbvios para o analisador:
// Remova BOM e caracteres de largura zero antes de analisar
const cleaned = raw.replace(/^\uFEFF/, '').replace(/[\u200B-\u200D]/g, '');
const data = JSON.parse(cleaned);
Terceiro: o tipo errado. JSON.parse(undefined) informa "undefined" is not valid JSON; JSON.parse(someObject) informa Unexpected token o (o objeto foi convertido para "[object Object]", e o é ilegal na posição 1). Ambos significam "os dados já estão analisados" ou "nunca houve dados". Verifique o tipo, não a sintaxe:
let data = text;
if (typeof data === 'string') {
data = JSON.parse(data); // Analise apenas quando realmente for uma string
}
3. A posição aponta para frente; a causa está atrás
Dois erros enganam sobre a localização, e são as duas entradas mais mal interpretadas da tabela:
- Uma vírgula faltando:
{"a": 1 "b": 2}informaExpected ',' or '}' after property valuena linha de"b". O relato está correto, mas a correção fica no fim da linha anterior. - Um colchete de fechamento faltando: um aninhamento profundo sem um
}ou]faz o analisador engolir tudo até o fim da entrada e informarUnexpected end of JSON input. A posição é o fim do arquivo; a lacuna real pode estar bem antes. Busque para trás o último{ou[não fechado — contar pares é melhor do que olhar a olho nu.
A técnica geral é a bisseção: corte o texto antes da posição informada e analise-o isoladamente. Se for analisado, o problema está perto da posição informada; se não, bisseccione mais para trás. O limite do primeiro trecho que falha é o local real do erro. Para arquivos grandes, formate o documento primeiro — com a indentação alinhada, o nível que falta fica visível na hora (o formatador JSON online funciona bem para isso).
4. Quatro estados "falsamente saudáveis" que são analisados bem mas se comportam mal
Pior do que um erro é nenhum erro e dados errados. Nos quatro casos o JSON é válido e o analisador está satisfeito — o problema é o formato dos dados:
- Codificação dupla: o documento inteiro passou por
JSON.stringifyduas vezes, então a análise produz uma string, não um objeto. Setypeof result === 'string', analise de novo — mas encontre e corrija a serialização dupla na origem. - Chaves duplicadas sobrescrevem silenciosamente:
{"name": "Tom", "name": "Jerry"}é JSON válido, a maioria dos analisadores não reclama, e o segundo valor vence. Isso morde ao mesclar dados de várias fontes; exponha o problema com um validador JSON estrito antes que ele morda você. - NDJSON tratado como um único documento: APIs de streaming emitem um objeto por linha; analisar o texto inteiro falha com
Unexpected non-whitespace character after JSON. Separe por\ne analise linha a linha. - Perda silenciosa de precisão numérica: inteiros acima de
2^53 - 1(IDs snowflake) voltam com os últimos dígitos zerados, sem erro nenhum. Transmita IDs como strings.
O fio condutor: o analisador acredita que está tudo bem. Então, quando os dados da API parecerem errados, imprima os primeiros 80 caracteres do texto cru e seu typeof primeiro — confirme o formato antes de discutir o conteúdo.
5. Torne os erros impossíveis na hora de escrever
A tabela de consulta é a ferramenta para depois do fato; a prevenção é a ferramenta para antes do fato. Quatro hábitos interceptam a maioria dos erros antes que aconteçam:
// 1. Duas verificações antes de analisar qualquer resposta
const response = await fetch('/api/users');
if (!response.ok) {
throw new Error(`HTTP ${response.status}: a API não retornou dados`);
}
const contentType = response.headers.get('content-type') ?? '';
if (!contentType.includes('application/json')) {
throw new Error(`Esperava JSON, recebi ${contentType}`);
}
const data = await response.json(); // 2. json() já analisa — não analise de novo
- Serialize para gerar, nunca concatene:
JSON.stringify()trata aspas, quebras de linha e caracteres de controle corretamente; strings montadas à mão são a principal origem deBad control charactereUnterminated string. - Sempre capture: um erro de
JSON.parselançado é uma falha síncrona a menos que algo o capture. Para entrada não confiável — localStorage, arquivos externos — o bloco catch precisa de um valor padrão ou de relato de erro explícito. - Delegue a estrutura ao Schema: sintaxe válida não significa estrutura válida. Campos ausentes e tipos errados pertencem à validação JSON Schema na fronteira; veja o que o JSON Schema resolve.
6. O caminho de decisão rápido
Compacte o artigo inteiro em uma ordem de decisão. Ao ver um erro, pegue primeiro a posição e o token:
- Posição 0 → verifique as três origens:
<(HTML), BOM, tipo errado; end of input→ verifique corpo vazio ou truncado e depois busque para trás colchetes não fechados;Expected ...→ olhe o caractere anterior; geralmente é uma vírgula ou aspa faltando;after JSON data→ vários documentos foram concatenados; separe por linha;- Analisa bem mas os dados parecem errados → rode as quatro verificações de "falsamente saudável".
Combinado com a triagem passo a passo em como corrigir erros de análise JSON, 90% dos problemas de análise se resolvem em cinco minutos. Mantenha o texto do erro em favoritos — é o log de depuração que o analisador escreveu para você, a formulação muda uma vez a cada três anos, e uma consulta paga por um ano.
O que significa "Unexpected token in JSON"?
O analisador encontrou um caractere que é ilegal naquele ponto da gramática JSON. O token é o caractere rejeitado: < geralmente significa que a API retornou HTML, ' significa aspas simples, / significa um comentário, e uma letra comum geralmente significa uma chave sem aspas ou um literal exclusivo de JavaScript como undefined ou NaN. Leia o token primeiro, depois a posição, e a causa se estreita para uma.
Como corrijo "Unexpected end of JSON input"?
Duas origens: entrada vazia (corpo de resposta vazio, ou string vazia no localStorage) ou entrada truncada (download interrompido, cópia sem a última linha, limite de tamanho). Trate o caso vazio com if (!text) return; depois verifique a completude e feche o último {, [ ou " não fechado. Note que o erro também pode vir de um colchete faltando em nível profundo — a posição só por acaso é o fim do arquivo.
Por que Chrome, Firefox e Safari informam erros de forma diferente?
Os três navegadores trazem engines JS diferentes (V8, SpiderMonkey, JavaScriptCore), e cada um formula seus erros à sua maneira; o MDN documenta todas as variantes oficiais. Mas os três erros carregam os mesmos três elementos — posição, expectativa, realidade — com semântica um a um. Traduza para a formulação do V8 e use esta tabela como está.
A posição do erro aponta para algo que parece certo — e agora?
O erro real está antes. Casos típicos: uma vírgula faltando (informada na linha seguinte) e um colchete de fechamento faltando (informado no fim do arquivo). Caminhe para trás a partir da posição informada, token por token, ou bisseccione: analise a primeira metade isoladamente, e o limite do primeiro trecho que falha é o local real do erro.