← Tous les articles

Unexpected Token o en JSON à la position 1 : causes et correctif

Ce « o » minuscule est le deuxième caractère de « [object Object] ». Vous avez passé un objet JavaScript à JSON.parse() au lieu d'une chaîne. Voici toutes les variantes de cette erreur et le correctif d'une ligne pour chacune.

SyntaxError: Unexpected token o in JSON at position 1 — ce o minuscule est le second caractère de [object Object]. Cela signifie que vous avez passé un objet JavaScript directement à JSON.parse() au lieu d'une chaîne JSON. Cet article explique chaque variante de cette erreur et comment la corriger en moins d'une minute.

Pourquoi l'erreur indique « token o »

Lorsque vous passez une valeur non-chaîne à JSON.parse(), JavaScript la convertit d'abord en chaîne. Un objet ordinaire est converti en "[object Object]". Le parseur voit [ à la position 0 (valide — début d'un tableau), puis o à la position 1 (invalide — ce n'est pas un élément de tableau valide). D'où : Unexpected token o at position 1.

JSON.parse({})
// Équivaut à : JSON.parse("[object Object]")
// SyntaxError: Unexpected token o in JSON at position 1

Cause la plus fréquente : ne pas awaiter response.json()

C'est la source numéro un de cette erreur dans le code réel. Un objet Response de fetch() n'est pas une chaîne — c'est un wrapper autour d'un ReadableStream. Le passer à JSON.parse() le convertit en "[object Response]".

// ❌ Faux — response est un objet Response, pas une chaîne
const response = await fetch('/api/user');
const data = JSON.parse(response);
// SyntaxError: Unexpected token o in JSON at position 1

// ✓ Correct — laissez le navigateur parser le flux en JSON
const data = await response.json();

De même, si vous appelez response.text() sans await, vous obtenez un objet Promise (qui est converti en "[object Promise]").

// ❌ await manquant — text est une Promise, pas une chaîne
const text = response.text();
const data = JSON.parse(text);
// SyntaxError: Unexpected token o in JSON at position 1

// ✓ Correct
const text = await response.text();
const data = JSON.parse(text);

Autres objets qui déclenchent cette erreur

Ce que vous avez passéCe que JS convertit enToken d'erreur
{} ou tout objet ordinaire"[object Object]"token o à la position 1
undefined"undefined"token u à la position 0
true / false"true" / "false" — en fait du JSON valide !aucune erreur
Un objet Response"[object Response]"token o à la position 1
Une Promise"[object Promise]"token o à la position 1
null"null" — JSON valideaucune erreur (retourne null)

Cause : passer un objet au lieu de le sérialiser

Une erreur connexe : essayer de « parser » un objet JavaScript que vous avez déjà en mémoire. JSON.parse() prend une chaîne ; si vous avez déjà un objet, vous n'avez pas besoin de le parser.

const config = { host: 'localhost', port: 3000 };

// ❌ Inutile — config est déjà un objet
const parsed = JSON.parse(config);

// ✓ Si vous voulez un clone profond, utilisez structuredClone ou stringify + parse
const clone = JSON.parse(JSON.stringify(config));

// ✓ Si vous voulez l'envoyer, utilisez JSON.stringify
const body = JSON.stringify(config);

Cause : Python ou un autre backend renvoie un Content-Type incorrect

Parfois le serveur renvoie un message d'erreur en texte brut (comme "ok" ou "not found") avec un statut 200 et sans en-tête Content-Type. Le frontend suppose du JSON, appelle response.json(), et obtient une erreur de token inattendu car le corps n'est pas du JSON valide.

// Le serveur envoie la chaîne littérale : ok
// Le navigateur essaie de la parser comme du JSON :
JSON.parse("ok")
// SyntaxError: Unexpected token o in JSON at position 0

Correction : Vérifiez toujours response.ok et response.headers.get('Content-Type') avant d'appeler response.json() :

const response = await fetch('/api/action');
if (!response.ok) {
  const text = await response.text();   // sûr — n'est peut-être pas du JSON
  throw new Error(`HTTP ${response.status}: ${text}`);
}
const data = await response.json();

Variantes moins courantes de [object X]

Toute valeur dont le toString() renvoie une chaîne commençant par [object déclenche la même erreur à la position 1. Au-delà de [object Object], celles qu'on voit réellement dans le code :

  • [object Module] — passer le résultat d'un import dynamique : const mod = await import('./data.json', { with: { type: 'json' } }) ; vous voulez mod.default, pas mod.
  • [object AsyncFunction] — passer la référence d'une fonction async au lieu de l'appeler : sérialisez fn() (la valeur résolue de la promesse), pas fn.
  • [object HTMLDocument] — passer document par erreur (par ex. depuis un fragment de débogueur oublié).
  • [object FormData] — utiliser fetch(url, { body: formData }) est correct, mais JSON.parse(formData) ne l'est pas — convertissez d'abord avec Object.fromEntries(formData).

Checklist de correction rapide

  • fetch + JSON.parse ? Remplacez par await response.json().
  • Un await manque quelque part dans la chaîne ? Chaque appel async avant le parsing doit être awaité.
  • Vous avez déjà un objet ? Pas besoin de le parser — utilisez-le directement ou clonez-le avec structuredClone().
  • Le serveur renvoie autre chose que du JSON en cas d'erreur ? Lisez avec response.text(), pas response.json(), lorsque la réponse peut ne pas être du JSON.

Foire aux questions

Que signifie « Unexpected token o in JSON at position 1 » ?

Vous avez passé un objet JavaScript à JSON.parse(). JavaScript convertit l'objet en la chaîne "[object Object]" ; le parseur accepte [ à la position 0 mais rejette le o à la position 1.

Comment le corriger avec fetch ?

N'appelez pas JSON.parse(response). Utilisez await response.json(), qui lit le flux de réponse et le parse pour vous. Assurez-vous que chaque étape de la chaîne est awaitée.

Ai-je besoin de JSON.parse si j'ai déjà un objet ?

Non. JSON.parse() ne convertit qu'une chaîne JSON en valeur. Si vous tenez déjà un objet, utilisez-le directement, ou faites une copie profonde avec structuredClone() plutôt que JSON.parse(JSON.stringify(obj)).

« Unexpected token o » est-il identique à « [object Object] is not valid JSON » ?

Ils partagent la même cause racine — un objet converti en chaîne avant d'être parsé. Les builds V8 plus récents affichent [object Object] is not valid JSON ; les anciens affichent Unexpected token o. Voir Corriger « [object Object] is not valid JSON » pour l'analyse complète.

Inspectez la réponse brute

Si vous ne savez pas ce que renvoie votre API, collez le corps brut dans JSON Fix pour le valider. Si ce n'est pas du JSON valide, le validateur vous dira exactement ce qui ne va pas.