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 analisa pela metade nem adivinha a intenção. Um caractere fora do lugar em um documento de vários megabytes gera o mesmo SyntaxError genérico que um caractere fora do lugar num arquivo de configuração de cinco linhas. Este guia percorre os erros que você vai encontrar no V8 (Node.js e Chrome), o que cada um diz 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 comentários são legais, porque o motor analisa esse código como qualquer outro. JSON é uma gramática muito menor e mais rigorosa (RFC 8259), e JSON.parse() impõe cada uma de suas regras sem fallback. O parser lê da esquerda para a direita e para no primeiro token que não se encaixa na gramática naquela posição.

Os criadores escolheram isso de propósito. Um parser JSON tolerante aceitaria documentos ligeiramente diferentes em cada implementação, justamente o problema de interoperabilidade que o JSON queria evitar. O custo: as mensagens de erro são curtas e só indicam posição. 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 aparecem o tempo todo quando alguém digita JSON à mão ou copia de código 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 gera outra mensagem: o V8 moderno sabe que esperava um nome de propriedade e reporta `Expected property name or '}' in JSON at position 2` sem citar o identificador isolado. Nos dois casos 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

O JSON proíbe quebra de linha, tabulação ou outro caractere de controle (qualquer coisa abaixo de U+0020) dentro de uma string. Escape-o como `\n`, `\t` e assim por diante. O problema aparece mais quando o código monta JSON concatenando 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.

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 em vez de só um token. Escape o caractere em vez de deixá-lo cru: `"line one\nline two"`.

Chaves duplicadas, NaN/Infinity/undefined e caracteres BOM

Três modos de falha mais silenciosos merecem nome. Primeiro, chaves duplicadas num objeto JSON não geram erro de análise. `{ "id": 1, "id": 2 }` é analisado sem problema, e JSON.parse mantém a última ocorrência (`id: 2`) e descarta a primeira sem aviso. A RFC 8259 diz que os nomes 'deveriam' ser únicos, mas não exige que os parsers rejeitem duplicatas, então seu parser segue a especificação, e quem revisa o código deixa esse bug passar com facilidade.

Segundo, `NaN`, `Infinity` e `undefined` são JavaScript válido, mas não são tokens JSON. O JSON tem `number` sem os valores especiais do IEEE-754, e não tem `undefined` (só `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). `JSON.stringify` converte `NaN`/`Infinity` para `null` e descarta valores `undefined`, então esse erro costuma significar que alguém escreveu o JSON à mão ou que uma fonte não-JS assumiu semântica de JS.

Terceiro, um byte-order-mark UTF-8 (U+FEFF) no início de um arquivo quebra o `JSON.parse` quando você lê o arquivo como string crua, e produz `Unexpected token '\ufeff'... is not valid JSON` na posição 0. Editores do Windows e algumas ferramentas Java/.NET o adicionam ao salvar UTF-8. O problema é do `JSON.parse` sobre uma string: o `Response.json()` da Fetch API decodifica texto UTF-8 e remove um BOM inicial durante a decodificação, então os mesmos bytes podem se comportar de forma diferente via HTTP e lidos do disco com `fs.readFileSync(path, 'utf8')`.

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 que você passou, não um número de linha. O Node (v20+) também anexa um `(line X column Y)`, mas runtimes e navegadores mais antigos dão só o deslocamento cru. Duas coisas confundem as pessoas. A posição marca onde o parser notou a gramática quebrada, e para uma vírgula final ou um colchete faltando ela costuma ficar um token depois do seu erro. E se você formatou o JSON para ler enquanto depura a string minificada original, os deslocamentos não vão bater com o que aparece na tela.

Para um deslize de sintaxe pontual num documento curto, corrija à mão depois de achar a posição. Cole o documento num validador que destaque o caractere em vez de contar deslocamentos. Para um arquivo grande com vários erros não relacionados, JSON saído de uma ferramenta upstream com bugs, ou JSON estragado por várias rodadas de copiar e colar, a correção manual toma tempo demais. Aí vale automatizar. O JSON Validator do JSONForge aponta cada violação de schema com um caminho preciso assim que o documento é analisável, e o JSON Repair corrige 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 de sempre são um caractere byte-order-mark (BOM) no início e 'aspas inteligentes' ou travessões que entram ao copiar de um editor de texto, app de chat ou PDF. Na maioria das fontes eles parecem iguais a uma aspa dupla comum ou a um hífen, mas são caracteres Unicode diferentes que o JSON.parse rejeita. Abra o arquivo num editor que mostre caracteres ocultos/não-ASCII, ou compare com uma versão que você sabe estar 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 cada implementação decide. O JSON.parse do JavaScript mantém 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. Não conte com chaves duplicadas se comportando igual em todos os ambientes.
Posso fazer o JSON.parse aceitar vírgulas finais ou comentários?
O JSON.parse em si, não. Ele implementa 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. Deixe a remoção por regex para scripts descartáveis, porque ela pode corromper vírgulas ou chaves 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 a linha e a coluna do problema. Você acha o ponto em segundos, e num arquivo grande o deslocamento cru de caracteres não diz nada a um humano.

Experimente estas ferramentas

Artigos relacionados