Skip to content
jsonforge.app
Voltar ao blog
Guia7 min de leitura

Erros comuns de análise de JSON e como corrigi-los

JSON.parse() não faz análise parcial nem tenta adivinhar a intenção — um único caractere fora do lugar em um documento de vários megabytes gera o mesmo SyntaxError genérico de um caractere fora do lugar num arquivo de configuração de cinco linhas. Este guia percorre os erros que você realmente vai encontrar no V8 (Node.js e Chrome), o que cada um está de fato dizendo e como decidir entre corrigir à mão ou rodar uma ferramenta automática de reparo.

Por que JSON.parse lança exceção em vez de adivinhar

Literais de objeto JavaScript são tolerantes: chaves sem aspas, vírgulas finais, strings com aspas simples e até comentários são todos legais, porque o código-fonte é analisado pelo mesmo motor que analisa todo o resto. JSON não é JavaScript — é uma gramática muito menor e mais rigorosa (RFC 8259), e JSON.parse() impõe cada regra dessa gramática sem fallback. Não existe JSON 'quase correto'; o parser lê da esquerda para a direita e para morto no primeiro token que não se encaixa na gramática naquela posição.

Essa é uma decisão de design deliberada, não uma limitação: um parser JSON tolerante aceitaria silenciosamente documentos sutilmente diferentes em implementações diferentes — exatamente o problema de interoperabilidade que o JSON foi inventado para evitar. O custo é que as mensagens de erro são telegráficas e posicionais, e não semânticas — o parser diz onde a gramática quebrou, não o que você quis escrever.

Vírgulas finais

O erro de JSON mais comum de todos é uma vírgula final esquecida ao editar um literal de objeto JavaScript (onde ela é legal) sem lembrar que não é legal em JSON.

Uma vírgula final após a última entrada do array/objeto é JSON inválido.
json
{
  "name": "Alice",
  "roles": ["admin", "editor"],
}

O V8 rejeita isso na chave de fechamento, e não na vírgula, porque a vírgula em si é gramática válida até o momento em que o parser espera outra propriedade e encontra `}` no lugar. Dependendo da sua versão do Node/Chrome, você verá algo como `Unexpected token '}', "...editor"],\n}"... is not valid JSON` (V8 mais recente, com um trecho) ou o antigo e mais telegráfico `Unexpected token } in JSON at position 47`. De qualquer forma, a correção é a mesma: apague a vírgula antes do colchete ou chave de fechamento.

Aspas simples e chaves sem aspas

O JSON exige aspas duplas para toda string e toda chave — sem exceções. Strings com aspas simples e chaves sem aspas são extremamente comuns quando o JSON é digitado à mão ou copiado de código-fonte JavaScript.

Estes dois são JSON inválido, embora sejam literais de objeto JS válidos.
json
{ 'name': 'Alice' }
{ name: "Alice" }

Uma aspa simples no início produz algo como `Unexpected token ''', "{ 'name'"... is not valid JSON`. Uma chave sem aspas é sutilmente diferente: o V8 moderno reconhece que um nome de propriedade era esperado e reporta `Expected property name or '}' in JSON at position 2`, em vez de culpar diretamente o identificador isolado. De qualquer forma, a correção é mecânica — envolva toda chave e todo valor de string em aspas duplas.

Quebras de linha e caracteres de controle sem escape dentro de strings

Uma quebra de linha, tabulação ou outro caractere de controle (qualquer coisa abaixo de U+0020) no interior de uma string JSON é ilegal — precisa ser escapado como `\n`, `\t` e assim por diante. Isso morde com mais frequência quando o JSON é gerado concatenando ingenuamente um valor de várias linhas (uma mensagem de log, um trecho de código, um comentário de usuário) num literal de string sem escapá-lo antes.

Uma quebra de linha literal dentro do valor da string, sem escape.
json
{
  "message": "line one
line two"
}

Isso produz `SyntaxError: Bad control character in string literal in JSON at position 21` — um dos poucos erros de JSON que nomeia o problema real em vez de apenas um token. A correção é escapar o caractere em vez de deixá-lo aparecer cru: `"line one\nline two"`.

Chaves duplicadas, NaN/Infinity/undefined e caracteres BOM

Três modos de falha mais silenciosos que valem conhecer pelo nome. Primeiro, chaves duplicadas num objeto JSON não geram erro de análise algum — `{ "id": 1, "id": 2 }` é analisado com sucesso, e JSON.parse silenciosamente mantém a última ocorrência (`id: 2`) e descarta a primeira. A RFC 8259 diz que os nomes 'deveriam' ser únicos, mas não exige que os parsers rejeitem duplicatas — então isso é comportamento em conformidade com a especificação, fácil de passar despercebido em review, e não um bug no seu parser.

Segundo, `NaN`, `Infinity` e `undefined` são todos JavaScript válidos, mas nenhum deles é um token JSON válido — o JSON só tem `number`, não os valores especiais do IEEE-754, e não tem conceito de `undefined` (apenas `null`). `{ "value": NaN }` lança `Unexpected token 'N', ..."value":NaN}"... is not valid JSON` (ou `Unexpected token N in JSON at position 10` em motores mais antigos). Se você está serializando a partir do JavaScript, `JSON.stringify` já converte `NaN`/`Infinity` para `null` e descarta valores `undefined` completamente — o erro geralmente significa que o JSON foi escrito à mão ou veio de uma fonte não-JS que assumiu semântica de JS.

Terceiro, um byte-order-mark UTF-8 (U+FEFF) bem no início de um arquivo — frequentemente adicionado em silêncio por editores do Windows ou por algumas ferramentas Java/.NET ao salvar UTF-8 — quebra o `JSON.parse` quando o arquivo é lido como string crua, produzindo `Unexpected token '\ufeff'... is not valid JSON` na posição 0. Note que esse é especificamente um problema de `JSON.parse` sobre uma string: o `Response.json()` da Fetch API decodifica texto UTF-8 e remove um BOM inicial como parte dessa decodificação, então os mesmos bytes servidos via HTTP e lidos do disco com `fs.readFileSync(path, 'utf8')` podem se comportar de forma diferente.

Lendo a posição, e quando usar uma ferramenta de reparo

A `position` num erro de JSON.parse é um deslocamento de caracteres indexado a partir de zero na string exata que você passou, não um número de linha — o Node (v20+) adicionalmente calcula e anexa um `(line X column Y)` por conveniência, mas runtimes e navegadores mais antigos dão apenas o deslocamento cru. Duas coisas confundem as pessoas: a posição reportada é onde o parser notou que a gramática quebrou, que para uma vírgula final ou um colchete faltando costuma estar um token depois de onde você realmente errou; e se você formatou o JSON para legibilidade mas está depurando a string minificada original, os deslocamentos não vão corresponder ao que você vê na tela.

Para um deslize de sintaxe pontual num documento curto, corrigir à mão depois de localizar a posição é mais rápido do que qualquer ferramenta — cole o documento num validador que destaque o caractere exato em vez de contar deslocamentos manualmente. Para um arquivo grande com vários erros não relacionados, JSON gerado por uma ferramenta upstream com bugs, ou JSON que passou por várias rodadas de copy-paste com perdas, a correção manual deixa de valer o tempo. Esse é o momento de recorrer a algo automático: o JSON Validator do JSONForge aponta cada violação de schema com um caminho preciso assim que o documento ao menos é analisável, e o JSON Repair tenta corrigir automaticamente erros estruturais comuns (aspas faltando, vírgulas finais, colchetes desbalanceados) quando a entrada está danificada demais para corrigir um erro de cada vez.

FAQ

Por que JSON.parse falha num arquivo que parece totalmente certo?
Os culpados invisíveis mais comuns são um caractere byte-order-mark (BOM) no início e 'aspas inteligentes' ou travessões introduzidos ao copiar de um editor de texto, app de chat ou PDF — ambos parecem idênticos a uma aspa dupla comum ou a um hífen na maioria das fontes, mas são caracteres Unicode diferentes que o JSON.parse rejeita. Abra o arquivo num editor que revele caracteres ocultos/não-ASCII, ou faça um diff contra uma versão sabidamente boa.
Por que uma chave duplicada não é tratada como erro?
A especificação do JSON (RFC 8259) diz que os nomes de membros de objeto 'deveriam' ser únicos, mas não obriga os parsers a impor isso, então o comportamento é definido pela implementação. O JSON.parse do JavaScript mantém silenciosamente a última duplicata e descarta as anteriores; os parsers de algumas outras linguagens lançam exceção, e outros mantêm a primeira ocorrência. Nunca dependa de um comportamento de chaves duplicadas consistente entre ambientes.
Posso fazer o JSON.parse aceitar vírgulas finais ou comentários?
Não o JSON.parse em si — ele implementa estritamente a gramática JSON, sem opções de tolerância. Se você precisa de comentários ou vírgulas finais, use um parser de superconjunto como o JSON5 ou um parser com suporte a JSONC, ou remova a sintaxe problemática antes de chamar JSON.parse. Não tente escrever sua própria remoção por regex para além de scripts descartáveis — é fácil corromper acidentalmente vírgulas ou chaves que aparecem dentro de valores de string.
Qual a forma mais rápida de encontrar a localização exata de um erro num arquivo enorme?
Não conte caracteres à mão. Cole o documento num formatador ou validador que destaque visualmente a linha e coluna exatas do problema — isso transforma uma contagem manual de vários minutos numa consulta instantânea, especialmente quando o arquivo é grande o suficiente para o deslocamento de caracteres cru não significar nada para um humano.

Experimente estas ferramentas

Artigos relacionados