Cómo corregir errores de análisis JSON: comprobar Unexpected token paso a paso
En resumen: Convierte los errores de JSON.parse en una línea y un carácter y después descarta seis causas: comas finales, comillas simples, comentarios, caracteres de control, BOM y truncamiento.

En resumen: ante un error de análisis, lee la línea y columna indicadas para encontrar el primer carácter ilegal y después decide si es una comilla que falta, una coma que falta, una coma final, un BOM o un truncamiento: no vuelvas a leer todo el documento desde el principio.
Un mensaje de error nunca te dice "qué está mal"; solo te dice "dónde ya no pudo continuar el analizador". Esas dos posiciones a menudo no están en el mismo lugar.
1. Primero, traduce el error a coordenadas
El mismo JSON roto produce errores completamente distintos en diferentes lenguajes, pero todos se pueden convertir en "qué línea, qué carácter":
| Entorno | Error típico | Cómo leerlo |
|---|---|---|
| Navegador / Node | Unexpected token } in JSON at position 42 |
position es un desplazamiento de caracteres base 0, no un número de línea |
| Node 20+ | Unexpected non-whitespace character after JSON at position 42 |
significa que la primera parte es válida y el contenido extra empieza después de 42 |
| Java Jackson | Unexpected character ('}' (code 125)): was expecting ... at [Source: (String)..."..." ; line: 3, column: 1] |
da directamente línea y columna, la más usable de todas |
| Python | json.decoder.JSONDecodeError: Expecting ',' delimiter: line 3 column 1 (char 42) |
char es el desplazamiento; lo que importa es línea y columna |
| Go | invalid character '}' looking for beginning of object key string |
solo da el carácter, así que hay que retroceder y localizarlo por tu cuenta |
Una vez que tengas la posición, pega el JSON en el analizador JSON en línea; la herramienta coloca el cursor en la ubicación del error y resalta el número de línea y columna: este paso ahorra el 90% de mirar caracteres a ojo.
2. Seis errores de alta frecuencia
1. Coma final
{
"name": "json",
"version": 1,
}
Hay una coma de más antes de }. La especificación JSON no permite comas finales, mientras que los literales de objeto de JavaScript sí, así que la configuración copiada del código es la más propensa a traerla. Solución: borra la última coma; si estos datos viven originalmente en un archivo JS, pasa a la conversión a JSON5 en vez de forzarlos a JSON.
2. Comillas simples y claves sin comillas
{ 'name': 'json' }
{ name: "json" }
Las cadenas JSON solo pueden usar comillas dobles, y las claves también deben ser cadenas entre comillas dobles. Estas dos son sintaxis relajada de JSON5 / JavaScript, no JSON. Una comilla doble dentro de una cadena debe escribirse como \", y una barra invertida como \\.
3. Comentarios
{
// Tiempo de espera en milisegundos
"timeout": 3000
}
La gramática de RFC 8259 no tiene lugar para comentarios. O borras los comentarios, o guardas como .jsonc / .json5 y usas un analizador que admita comentarios. Para los compromisos entre los distintos "esquemas de comentarios", consulta Cómo escribir comentarios en JSON.
4. Saltos de línea en bruto y caracteres de control dentro de cadenas
{"sql": "SELECT *
FROM t"}
Las cadenas JSON no pueden contener saltos de línea, tabuladores ni los caracteres de control U+0000–U+001F en bruto; hay que escribirlos como \n, \t, \u0009. Cuando metas texto multilínea en JSON, escápalo una vez en un editor primero, o trátalo de forma uniforme con Minificar y escapar JSON.
5. Cabecera BOM
El UTF-8 guardado por el Bloc de notas de Windows lleva los tres bytes EF BB BF. JSON.parse informa de Unexpected token cuando encuentra un BOM, y el ojo no puede verlo en absoluto. Cómo detectarlo: inspecciona la cabecera del archivo en hexadecimal, o copia el contenido a una herramienta en línea y comprueba si el primer carácter se muestra como . Solución: guarda como "UTF-8 sin BOM".
6. Contenido truncado
Un registro que solo imprimió los primeros 4096 caracteres, una respuesta de API cortada por un gateway, una descarga interrumpida: el sello distintivo de esta clase es "el error está al final" y los recuentos de corchetes no cuadran. Cuenta primero los corchetes: si los cierres de { y [ no coinciden, es truncamiento, no un error de sintaxis. En ese caso no arregles nada: ve a buscar los datos completos.
3. Dos falsas alarmas relacionadas con texto chino y escapes
El chino se convierte en \u4e2d\u6587: esto es un escape JSON válido, no texto corrupto. Tras el análisis, el valor se restaura al chino; la forma \u solo aparece cuando miras directamente la cadena en bruto. Cuando necesites mostrárselo a personas, simplemente sácalo con la herramienta de formato; solo tienes que preocuparte por la estrategia de escape cuando el chino deba sobrevivir en una URL o un registro.
El chino se convierte en texto corrupto como 涓枃: esto es un problema de codificación, no de JSON. Ocurre cuando los bytes UTF-8 se decodifican como GBK, produciendo este patrón regular de "tres caracteres en lugar de un carácter chino". Comprueba el Content-Type: application/json; charset=utf-8 de la cabecera de la respuesta y si se especifica explícitamente encoding='utf-8' al leer el archivo.
4. Un flujo de reparación de cinco minutos
- Pégalo en la herramienta: usa primero el analizador en línea para localizar el primer error y corrige solo uno a la vez;
- Valida tras cada corrección: vuelve a analizar después de cada cambio, para que corregir varios puntos a la vez no haga que los nuevos errores oculten el antiguo;
- Minifica una vez: elimina los espacios con Minificar y analiza de nuevo; esto distingue los "errores estructurales" de los "problemas de espacios o saltos de línea";
- Compara la estructura: si tras un cambio aparece de repente un error, usa diff de JSON contra la versión anterior; la diferencia suele ser esa única coma;
- Validación a nivel de campo: si la sintaxis pasa pero la capa de negocio lo rechaza (campo ausente, tipo equivocado), eso entra en la validación con JSON Schema, no es un problema de sintaxis.
5. Por qué uno de dos fragmentos JSON "idénticos" se analiza y el otro no
La causa más habitual son los caracteres invisibles: la coma de ancho completo ,, las comillas de ancho completo “”, el espacio duro U+00A0, el espacio de ancho cero U+200B. En pantalla son casi indistinguibles de sus equivalentes de medio ancho, pero ninguno forma parte de la gramática JSON.
Solo hay una forma de saberlo: copia el contenido alrededor del carácter problemático e inspecciona los puntos de código byte a byte. Ejecutar lo siguiente en la consola del navegador lista todos los caracteres que no son ASCII y quedan fuera de los rangos chinos:
[...text].filter((ch) => {
const code = ch.codePointAt(0);
return code > 127 && !(code >= 0x4e00 && code <= 0x9fff);
});
Si en la salida aparecen 0x201c (comilla doble izquierda), 0xff0c (coma de ancho completo) o 0x00a0, ellos son los culpables.
6. Prevenir es más barato que reparar
- Ejecuta una comprobación de análisis sobre los archivos de configuración antes de confirmar; en CI basta una línea:
node -e "JSON.parse(require('fs').readFileSync('config.json','utf8'))"; - Genera las respuestas de la API con una biblioteca de serialización; nunca concatenes cadenas a mano: las cadenas construidas a mano son la única fuente de comas finales y comillas que faltan;
- Al registrar JSON, llama primero a
JSON.stringifyen vez de interpolarlo en una plantilla, para que una carga a medio escribir no se confunda con un mensaje completo.
Preguntas frecuentes
¿Cómo localizo rápidamente la posición de un error de sintaxis JSON?
Toma la posición o línea/columna que indica el analizador; position es un desplazamiento de caracteres base 0, no un número de línea, mientras que Java Jackson y Python dan directamente línea y columna. Pega el JSON en el analizador JSON en línea y la herramienta pone el cursor en la ubicación del error y resalta línea y columna. Si el error está al principio, revisa la cabecera del archivo por si hay un BOM y busca caracteres invisibles.
¿Por qué la configuración copiada del código es tan propensa a llevar una coma final?
La especificación JSON prohíbe las comas finales, mientras que los literales de objeto de JavaScript las permiten, así que la configuración copiada de código JS las arrastra fácilmente. La solución es simplemente borrar la última coma; si los datos pertenecen de todos modos a un archivo JS, cambiar a la conversión a JSON5 encaja mejor que forzarlos a JSON.
¿Puedo analizar un archivo de configuración con comentarios como JSON normal?
No: la gramática de RFC 8259 no tiene lugar para comentarios, así que analizarlo directamente da error. O borras los comentarios, o guardas como .jsonc / .json5 y usas un analizador que admita comentarios. Para los compromisos entre los distintos esquemas de comentarios, consulta Cómo escribir comentarios en JSON.