Quase todos os erros de JSON que voce vai encontrar se reduzem a uma de nove coisas. A mensagem do parser raramente diz qual e, porque a maioria relata o token onde engasgou em vez do erro que voce cometeu, e nao sao a mesma coisa. Aqui esta cada erro, a mensagem que voce provavelmente vera, e a correcao que o resolve.
Se quiser acompanhar, cole qualquer um destes exemplos no validador JSON. Ele identifica o erro e marca a linha.
1. Uma virgula no final
{
"name": "ana",
"role": "admin",
}
A virgula depois da ultima propriedade e legal em JavaScript e ilegal em JSON. A maioria dos parsers reporta isso na chave de fechamento, uma linha abaixo da virgula real, e por isso as pessoas olham para a chave e nao veem nada de errado.
Remova a virgula. Se voce esbarra nisso constantemente porque edita arquivos de configuracao a mao, a ferramenta de reparacao JSON remove-as e mostra cada uma que removeu.
2. Aspas simples
{ 'name': 'ana' }
JSON tem uma unica sintaxe para strings e usa aspas duplas. Aspas simples sao um habito de JavaScript. A correcao e mecanica, e vale mais usar uma ferramenta do que fazer a mao se o documento for grande, porque uma aspa dentro de uma string tem que ser escapada em vez de simplemente trocada.
3. Chaves sem aspas
{ name: "ana" }
As chaves de objetos sao strings, e strings levam aspas. Literais de objetos em JavaScript permitem omitir aspas, e e de sempre que isso acontece: alguem copiou um objeto de um arquivo fonte e esperava que fosse JSON. Nao e.
4. Comentarios
{
// the account owner
"name": "ana"
}
JSON nao permite comentarios. Douglas Crockford os removeu de proposito, porque
as pessoas os usavam para carregar diretrizes de parsing. Tanto // quanto /* */ sao
erros. Se os comentarios importam, mantenha-os em um arquivo fonte e gere o JSON
a partir dele, ou mova a anotacao para um campo real como "_comment".
5. NaN, Infinity e undefined
{ "score": NaN, "limit": Infinity }
Nenhum desses existe em JSON. Nao ha sintaxe para eles de forma alguma, e por isso
o erro normalmente aparece como uma palavra solta inesperada. Python escreve NaN e
Infinity quando voce exporta floats sem cuidado, e JavaScript produz
undefined a partir de uma propriedade ausente.
Voce tem que decidir em que se tornar, porque nao ha uma resposta sem perda.
null e a escolha mais comum, uma string como "NaN" e a outra. A ferramenta
de reparacao escolhe null e lista a mudanca separadamente das correcoes de pontuacao,
porque esta altera seus dados e nao apenas sua formatacao.
6. Palavras-chave com caixa incorreta
{ "active": True, "deleted": NULL }
As palavras-chave de JSON sao minusculas: true, false, null. True e None sao
do Python, NULL e do SQL e C. Um parser que diz “unexpected token T” esta dizendo
a verdade da maneira menos util possivel.
7. Uma quebra de linha dentro de uma string
{ "note": "first line
second line" }
Uma string de JSON nao pode abranger varias linhas. A quebra de linha tem que ser escrita como \n
dentro da string. Isso e comum quando alguem cola texto multilinha em um
arquivo de configuracao a mao, e o erro resultante aponta frequentemente para a proxima linha, nao para
a string que ficou aberta.
8. Numeros que JSON nao permite
{ "a": .5, "b": +1, "c": 007, "d": 1_000 }
Quatro regras separadas. Um numero precisa de um digito antes do ponto decimal, entao .5 e
0.5. Um sinal de mais no inicio nao e permitido. Um zero no inicio nao e permitido, o que
rejeita 007. Separadores de digitos sao uma caracteristica da linguagem, nao do JSON.
9. Um colchete nao fechado
{
"user": {
"name": "ana"
}
O parser chega ao final do arquivo e relata o erro la, entao a mensagem diz alguma coisa sobre a linha 200 de um documento de 200 linhas enquanto a chave que falta esta na linha 2. Este e o erro para o qual vale a pena ter uma boa ferramenta: o validador deste site relata a posicao do colchete que foi aberto e nunca fechado, em vez do final da entrada.
Os dois erros que nao sao erros de sintaxe
Dois documentos podem ser perfeitamente validos e ainda assim errados.
Uma chave duplicada e parseada sem problemas. A especificacao permite, e cada parser que voce provavelmente usa mantem o ultimo valor e descarta silenciosamente o anterior, de modo que os dados desaparecem sem nenhum erro em lugar nenhum:
{ "region": "eu-west-1", "retries": 3, "region": "us-east-1" }
O validador reporta duplicatas como avisos com ambos os numeros de linha, e ainda chama o documento valido, porque e o que a especificacao diz.
Um inteiro longo tambem e parseado sem problemas, e depois perde precisao no momento em que algo o le em um double:
{ "id": 1234567890123567890 }
Ler isso com uma biblioteca JSON tipica da 1234567890123567000. As
ferramentas aqui trabalham no fluxo de tokens em vez de parsear em um valor JavaScript, de modo que
o numero sobrevive a formatacao, minificacao e comparacao sem alterar. Isso e
tambem por que a ferramenta diff nao vai chamar dois inteiros de vinte digitos
iguais so porque colapsam no mesmo valor de ponto flutuante.
Como ler uma mensagem de erro corretamente
Duas habitos economizam a maior parte do tempo que as pessoas dedicam a isso.
Primeiro, trate a posicao reportada como onde o parser desistiu, nao onde voce errou. Uma virgula ausente e reportada no proximo token, um colchete nao fechado no final do arquivo, e uma virgula final na chave de fechamento.
Segundo, verifique o caractere antes da posicao reportada. Na grande maioria dos casos o erro real esta um token antes da reclamacao.
Se voce preferir nao fazer nenhuma das duas, cole o documento no validador e leia a mensagem, que nomeia a construcao errada em vez de citar o token que nao pudo ser parseado.