Expecting value: line 1 column 1 (char 0)
O Python está dizendo que o primeiríssimo caractere do que você entregou não é o começo de um valor JSON. Na prática isso quase nunca significa que o seu JSON está sutilmente malformado. Significa que o que você parseou não é JSON: uma página HTML de erro, um corpo vazio, uma mensagem em texto puro, ou nada. A posição é linha 1 coluna 1 porque o parser falhou antes de ler qualquer coisa.
Você também pode ver isso escrito assim
- json.decoder.JSONDecodeError: Expecting value
O V8 reescreveu a maior parte das suas mensagens de erro de JSON em 2022. A redação antiga ainda é o que a maioria dos resultados de busca mostra, mas nenhum runtime atual a emite.
Cole o seu JSON e veja exatamente onde ele quebra
Nada do que você cola sai do seu navegador. A lista de permissões connect-src transforma isso em uma garantia do navegador, e não em uma promessa. Confira você mesmo
O que realmente causa isso
Ordenados por quantas vezes cada um acaba sendo a resposta.
-
01 O corpo da resposta é HTML, não JSON
Uma página 404, um redirecionamento de login, um desafio do Cloudflare ou uma página de erro de proxy. A requisição deu certo no nível HTTP e devolveu um documento, só que não o que você esperava. Imprima os primeiros algumas centenas de caracteres antes de parsear e você vai ver na hora.
Quebra
r = requests.get(url) data = r.json() # JSONDecodeErrorFunciona
r = requests.get(url) if r.status_code != 200 or 'json' not in r.headers.get('content-type', ''): raise RuntimeError(f"{r.status_code} {r.headers.get('content-type')}: {r.text[:300]}") data = r.json() -
02 O corpo está vazio
Um HTTP 204, uma requisição barrada por rate limit que não devolveu nada, um WAF que descartou o corpo, ou um arquivo que existe mas tem zero bytes. Uma string vazia não é JSON válido. Os documentos válidos mais curtos são null, 0, "", [] e {}.
Quebra
json.loads("")Funciona
text = r.text if not text.strip(): return None data = json.loads(text) -
03 Você está lendo um arquivo que não é JSON
Um CSV, um arquivo de log, um pickle do Python, ou um arquivo JSON Lines em que cada linha é um documento separado. Para JSON Lines, faça o parsing linha a linha em vez de tudo de uma vez.
Quebra
with open('events.jsonl') as f: data = json.load(f) # Expecting value, or Extra dataFunciona
with open('events.jsonl') as f: data = [json.loads(line) for line in f if line.strip()] -
04 A autenticação falhou e a API devolveu uma mensagem em texto puro
Muitas APIs devolvem "Unauthorized" ou "Forbidden" como texto puro com 401 ou 403, e não como JSON. Confira o código de status antes de olhar o corpo.
O mesmo erro em outros runtimes
O problema de fundo é idêntico; só muda a redação. Se um colega reportar uma dessas mensagens, ele está olhando exatamente para a mesma coisa que você.
| JavaScript (V8) | Unexpected token '<', "<!DOCTYPE "... is not valid JSON |
|---|---|
| JavaScript (V8), empty input | Unexpected end of JSON input |
| C# (Newtonsoft) | Unexpected character encountered while parsing value: <. Path '', line 0, position 0. |
Perguntas frequentes
- Por que sempre diz linha 1 coluna 1?
- Porque o parser falhou logo no primeiro caractere. Ele nunca chegou longe o bastante para alcançar a linha 2. Se o seu erro cita uma linha e coluna mais adiante, o problema está mesmo dentro do seu JSON e é outro erro.
- Como vejo o que realmente recebi?
- Imprima response.text[:500] antes de chamar .json(). Em nove de cada dez casos a resposta aparece já na primeira linha: um <!DOCTYPE html>, uma string vazia, ou uma mensagem curta em texto puro.
- json.loads aceita um objeto bytes?
- Aceita, desde o Python 3.6 o json.loads aceita bytes e bytearray além de str, e detecta UTF-8, UTF-16 e UTF-32. Então este erro não é causado por passar bytes.
Conserte agora
Cole o payload na ferramenta acima, ou vá direto para a que foi feita para este trabalho.
Valide o seu JSON