Expecting value: line 1 column 1 (char 0)
Python vous dit que le tout premier caractère de ce que vous lui avez donné n’est pas le début d’une valeur JSON. En pratique cela ne signifie presque jamais que votre JSON est subtilement malformé. Cela signifie que ce que vous avez analysé n’est pas du JSON : une page HTML d’erreur, un corps vide, un message en texte brut, ou rien du tout. La position est ligne 1 colonne 1 parce que l’analyseur a échoué avant d’avoir rien lu.
Vous pouvez aussi le voir écrit ainsi
- json.decoder.JSONDecodeError: Expecting value
V8 a réécrit la plupart de ses messages d’erreur JSON en 2022. L’ancienne formulation reste ce que montrent la plupart des résultats de recherche, mais aucun runtime actuel ne l’émet.
Collez votre JSON et voyez exactement où il casse
Rien de ce que vous collez ne quitte votre navigateur. La liste d’autorisation connect-src en fait une garantie du navigateur plutôt qu’une promesse. Vérifiez-le vous-même
Ce qui le provoque réellement
Classés selon la fréquence à laquelle chacun se révèle être la réponse.
-
01 Le corps de la réponse est du HTML, pas du JSON
Une page 404, une redirection vers la page de connexion, un challenge Cloudflare ou une page d’erreur de proxy. La requête a réussi au niveau HTTP et a renvoyé un document, simplement pas celui que vous attendiez. Affichez les quelques centaines de premiers caractères avant d’analyser et vous le verrez immédiatement.
Casse
r = requests.get(url) data = r.json() # JSONDecodeErrorFonctionne
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 Le corps est vide
Un HTTP 204, une requête limitée par le rate limiting qui n’a rien renvoyé, un WAF qui a supprimé le corps, ou un fichier qui existe mais fait zéro octet. Une chaîne vide n’est pas du JSON valide. Les documents valides les plus courts sont null, 0, "", [] et {}.
Casse
json.loads("")Fonctionne
text = r.text if not text.strip(): return None data = json.loads(text) -
03 Vous lisez un fichier qui n’est pas du JSON
Un CSV, un fichier de journal, un pickle Python, ou un fichier JSON Lines où chaque ligne est un document distinct. Pour du JSON Lines, analysez ligne par ligne plutôt que d’un seul bloc.
Casse
with open('events.jsonl') as f: data = json.load(f) # Expecting value, or Extra dataFonctionne
with open('events.jsonl') as f: data = [json.loads(line) for line in f if line.strip()] -
04 L’authentification a échoué et l’API a renvoyé un message en texte brut
Beaucoup d’API renvoient « Unauthorized » ou « Forbidden » en texte brut avec un 401 ou un 403, et non en JSON. Vérifiez le code de statut avant de regarder le corps.
La même erreur dans d’autres environnements
Le problème de fond est identique ; seule la formulation change. Si un collègue signale l’un de ces messages, il regarde exactement la même chose que vous.
| 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. |
Questions fréquentes
- Pourquoi dit-il toujours ligne 1 colonne 1 ?
- Parce que l’analyseur a échoué sur le tout premier caractère. Il n’est jamais allé assez loin pour atteindre la ligne 2. Si votre erreur nomme une ligne et une colonne plus loin, le problème est réellement dans votre JSON et c’est une autre erreur.
- Comment voir ce que j’ai réellement reçu ?
- Affichez response.text[:500] avant d’appeler .json(). Neuf fois sur dix la réponse est visible dès la première ligne : un <!DOCTYPE html>, une chaîne vide, ou un court message en texte brut.
- json.loads accepte-t-il un objet bytes ?
- Oui, depuis Python 3.6 json.loads accepte bytes et bytearray en plus de str, et détecte UTF-8, UTF-16 et UTF-32. Cette erreur n’est donc pas causée par le passage de bytes.
Corrigez-le maintenant
Collez le payload dans l’outil ci-dessus, ou allez directement à celui conçu pour ce travail.
Validez votre JSON