Si alguna vez has trabajado con JSON, es casi seguro que te has topado con el temido mensaje SyntaxError: Unexpected token. Aparece en las consolas del navegador, en las respuestas de las API, en los archivos de configuración y en los pipelines de CI/CD. El error en sí no es muy útil: te indica que algo está mal, pero rara vez explica qué.
Si quieres ir directamente a una solución, pega tu JSON defectuoso en el JSON Formatter y este resaltará la línea y el carácter exactos donde se produce el error. A partir de ahí, esta guía repasa las causas más comunes de los errores de análisis de JSON, te muestra exactamente cómo corregir cada una y te ofrece un flujo de trabajo fiable para detectar estos fallos antes de que provoquen problemas.
¿Qué significa realmente "Unexpected token"?
Los analizadores de JSON leen tu texto carácter por carácter. Cuando el analizador encuentra un carácter que no corresponde según la especificación de JSON, lanza un SyntaxError. El "unexpected token" es simplemente el carácter que el analizador no esperaba encontrar en esa posición.
Por ejemplo, toma este JSON roto, donde un valor de objeto usa comilla simple en lugar de comilla doble:
{
"name": "Alice",
"age": 30,
"city": 'Tokyo'
}
El V8 actual (el motor detrás de Chrome y Node.js) informa:
Unexpected token ''', ..." "city": 'Tokyo'
}" is not valid JSON
En lugar de un número de posición, el mensaje cita un fragmento del texto alrededor del error. Los motores más antiguos informaban un número de position (Unexpected token ' in JSON at position 14); la tabla de comparación más adelante en esta guía recoge ambas redacciones, porque todavía hay bastante material y respuestas de Stack Overflow que citan la anterior. De cualquier forma, contar caracteres manualmente en un archivo JSON grande resulta tedioso. Ahí es donde una herramienta como el JSON Formatter se vuelve indispensable: localiza la ubicación del error de forma visual.
Las 5 causas más comunes de los errores de análisis de JSON
1. Comas finales
Esta es posiblemente la causa más frecuente de los errores de análisis de JSON, sobre todo para quienes escriben JavaScript con regularidad. Los arreglos y objetos de JavaScript aceptan sin problema las comas finales. JSON no.
La versión defectuosa:
{
"name": "Alice",
"age": 30,
"city": "Tokyo",
}
La versión corregida:
{
"name": "Alice",
"age": 30,
"city": "Tokyo"
}
La coma que sigue a "Tokyo" es el problema. El V8 actual informa:
Expected double-quoted property name in JSON at position 53 (line 5 column 1)
El analizador lee la coma, espera otro par clave-valor y, como lo siguiente es una llave de cierre en lugar de una clave entre comillas, informa que esperaba un nombre de propiedad. No llama "unexpected token" a la llave, algo distinto de como lo describían los motores más antiguos.
Las comas finales también aparecen en los arreglos:
{
"colors": ["red", "green", "blue",]
}
Aquí el mensaje sí sigue el patrón "unexpected token":
Unexpected token ']', ..."", "blue",]
}" is not valid JSON
A diferencia del caso del objeto, en un arreglo la coma final deja ] como el siguiente carácter real, y V8 sí lo reporta como unexpected token. Elimina la coma que sigue a "blue" y el error desaparece:
{
"colors": ["red", "green", "blue"]
}
Este fallo es tan fácil de cometer que muchos editores de código ahora tienen ajustes para eliminar automáticamente las comas finales al guardar archivos JSON. Si tu editor lo admite, activa esa función.
2. Comillas simples en lugar de comillas dobles
JSON requiere comillas dobles para todas las cadenas y claves. Las comillas simples no son válidas, aunque tanto JavaScript como Python las acepten para los literales de cadena.
La versión defectuosa:
{
'name': 'Alice',
'age': 30
}
La versión corregida:
{
"name": "Alice",
"age": 30
}
Este error suele aparecer cuando alguien copia un diccionario de Python o un objeto literal de JavaScript e intenta usarlo como JSON. Los dos formatos se parecen, pero no son intercambiables.
Una búsqueda y reemplazo rápido de ' por " suele funcionar, pero ten cuidado si los valores de tus cadenas contienen apóstrofos. En ese caso, deberás escaparlos o gestionar el reemplazo con más cuidado. Pegar el texto en el JSON Formatter marcará las posiciones exactas donde aparecen las comillas simples para que puedas corregirlas una por una.
3. Claves sin comillas
En JavaScript, las claves de los objetos no necesitan comillas si son identificadores válidos. En JSON, cada clave debe ser una cadena entre comillas dobles, sin excepciones.
La versión defectuosa:
{
name: "Alice",
age: 30
}
La versión corregida:
{
"name": "Alice",
"age": 30
}
Esto tiende a ocurrir cuando alguien escribe JSON a mano o lo copia desde una fuente de JavaScript. También aparece en archivos de configuración donde alguien ha olvidado que JSON es más estricto que el lenguaje que utiliza habitualmente.
4. Comentarios en JSON
JSON no admite comentarios. Ni comentarios de una sola línea (//), ni comentarios de varias líneas (/* */), ni comentarios con almohadilla (#). Si un analizador encuentra cualquiera de estos, lanza un error.
La versión defectuosa:
{
// User's display name
"name": "Alice",
/* Age in years */
"age": 30
}
La versión corregida:
{
"name": "Alice",
"age": 30
}
Este es un verdadero punto de fricción. Es perfectamente razonable querer comentarios en un archivo de configuración, y muchos desarrolladores se frustran porque JSON no los permite. Algunas herramientas (como el settings.json de VS Code) en realidad usan un superconjunto llamado JSONC (JSON con comentarios), pero los analizadores de JSON estándar rechazan los comentarios de plano.
Para una comparación lado a lado de JSONC, JSON5, los campos _comment y los scripts de eliminación, y cuál elegir para archivos de configuración, datos o API, consulta ¿Puede JSON tener comentarios?. Si prefieres dejar JSON por completo, YAML admite comentarios de forma nativa con el carácter # y puedes convertir fácilmente entre ambos formatos. Echa un vistazo a nuestro artículo de consejos de formato de JSON para saber más sobre cómo gestionar archivos JSON complejos.
5. Caracteres BOM (Byte Order Mark)
Este es engañoso porque no se puede ver el problema con solo mirar el archivo. Un BOM es un carácter invisible (U+FEFF) que algunos editores de texto, especialmente en Windows, insertan justo al principio de un archivo. Le indica al editor qué codificación utiliza el archivo.
El analizador de JSON se topa con este carácter invisible antes de llegar al { o [ de apertura y no tiene ni idea de qué hacer con él. El V8 actual informa:
Unexpected token '', "{
"name"... is not valid JSON
Ese carácter que parece en blanco justo después de la primera ' es el BOM. Los motores más antiguos informaban Unexpected token in JSON at position 0 (position 0, porque el BOM siempre es el primer carácter del archivo).
Cómo corregirlo:
- Abre el archivo en un editor hexadecimal y elimina los tres primeros bytes (
EF BB BFpara el BOM de UTF-8). - En VS Code, haz clic en el indicador de codificación de la barra de estado, elige "Save with Encoding" y selecciona "UTF-8" (sin BOM).
- Usa una herramienta de línea de comandos:
sed -i '1s/^\xEF\xBB\xBF//' file.json
El estado antes (mostrado en hexadecimal):
EF BB BF 7B 0A 20 20 22 6E 61 6D 65 22 ...
El estado después:
7B 0A 20 20 22 6E 61 6D 65 22 ...
El contenido del archivo se ve idéntico en un editor de texto, pero ahora el analizador puede leerlo.
Otras causas que conviene conocer
Más allá de las cinco principales, aquí tienes algunos problemas adicionales que hacen tropezar a la gente:
Corchetes o llaves descompensados
La falta de un } o ] de cierre provocará un error de análisis, que normalmente se informa al final del archivo. Si tu JSON está profundamente anidado, encontrar el corchete descompensado a simple vista es casi imposible. Un formateador con emparejamiento de corchetes te ahorrará mucho tiempo.
Caracteres de control en las cadenas
Los saltos de línea, las tabulaciones y otros caracteres de control dentro de las cadenas de JSON deben escaparse. Un salto de línea literal dentro del valor de una cadena no es válido:
{"message": "Hello
World"}
Debería ser:
{"message": "Hello\nWorld"}
Números con ceros a la izquierda
Los números de JSON no pueden tener ceros a la izquierda. 007 no es JSON válido: debe ser 7, 0.07 o algún otro formato numérico estándar.
{
"code": 007
}
Corregido:
{
"code": 7
}
Uso de undefined o NaN
Los valores undefined y NaN de JavaScript no son valores válidos de JSON. Si serializas un objeto que contiene undefined, la mayoría de los serializadores omitirán la clave o lanzarán un error. NaN e Infinity se rechazan de forma similar.
Redacción anterior frente a la actual en los mensajes de error
Si estás depurando con una guía antigua, una respuesta de Stack Overflow en caché o una versión anterior de este artículo, y la redacción no coincide con lo que muestra tu consola, esta es la razón: la redacción de los mensajes de error de JSON.parse() ha cambiado a medida que evolucionaron los motores de JavaScript. El resto de esta guía usa ahora la redacción actual, pero la anterior sigue siendo útil para la búsqueda, porque todavía hay bastante material que la cita.
Dos cambios son los más importantes. Primero, los mensajes con token entre comillas (Unexpected token 'X', "..." is not valid JSON) ya no informan ningún número de position; en su lugar, citan un fragmento del texto alrededor del error. Segundo, los mensajes Expected ... in JSON at position N sí siguen informando una posición, pero ahora también añaden (line L column C), algo que la redacción anterior nunca incluía.
| Dónde aparece en esta guía | Redacción anterior | Salida actual de V8 (medida) |
|---|---|---|
| Ejemplo inicial (comilla simple) | Unexpected token ' in JSON at position 14 | Unexpected token ''', ..." "city": 'Tokyo'}" is not valid JSON |
| Causa 1: coma final (objeto) | no citada en el artículo (se describía como "la llave de cierre se convierte en el unexpected token") | Expected double-quoted property name in JSON at position 53 (line 5 column 1) |
| Causa 1: coma final (arreglo) | no citada en el artículo (misma descripción que el caso del objeto) | Unexpected token ']', ..."", "blue",]}" is not valid JSON |
| Causa 3: claves sin comillas | no citada en el artículo | Expected property name or '}' in JSON at position 4 (line 2 column 3) |
| Causa 4: comentarios | no citada en el artículo | Expected property name or '}' in JSON at position 4 (line 2 column 3) |
| Causa 5: BOM | Unexpected token in JSON at position 0 | Unexpected token '', "{ "name"... is not valid JSON |
JSON.parse(undefined) | Unexpected token u in JSON at position 0 | "undefined" is not valid JSON |
JSON.parse({ name: "Alice" }) | Unexpected token o in JSON at position 1 | "[object Object]" is not valid JSON |
| Respuesta HTML (tabla de entornos más abajo) | Unexpected token < in JSON at position 0 | Unexpected token '<', "<!DOCTYPE html>" is not valid JSON |
Medimos cada cadena de la columna "actual" ejecutando JSON.parse() sobre los mismos fragmentos JSON usados a lo largo de esta guía, en Node v26.3.1 / V8 14.6. El script y la salida en bruto están commiteados en scripts/benchmarks/json-parse-error-messages/ en el repositorio, así que cada fila es reproducible. No hemos verificado en qué versión de V8 cambió esta redacción: esta tabla solo confirma lo que informa el V8 actual hoy.
Búsqueda por síntoma: token u, token o y end of input
El carácter exacto que aparece en el mensaje de error acota bastante la causa. Las tres variantes siguientes apuntan cada una a un error distinto, y ninguna es un problema dentro de tu archivo JSON: todas ocurren antes de que el analizador llegue a ver JSON válido. (Si el token es <, el servidor devolvió una página HTML en lugar de JSON; consulta la tabla de entornos más abajo.)
Unexpected token u in JSON at position 0
JSON.parse recibió la cadena "undefined" — la u es su primera letra, y por eso los motores más antiguos nombraban el token u en el mensaje. Esto casi siempre significa que el valor que pasaste era undefined antes de intentar el análisis:
const raw = localStorage.getItem("settings"); // si la clave no existe, es null
JSON.parse(undefined); // lanza SyntaxError: "undefined" is not valid JSON
El V8 actual cita la cadena convertida completa ("undefined" is not valid JSON) en lugar de nombrar un solo carácter. Comprueba que el valor realmente existe antes de analizarlo. Una llamada a la API sin cuerpo, una clave de almacenamiento inexistente o un error de tipeo en el nombre de una variable son las causas habituales.
Unexpected token o in JSON at position 1
El analizador recibió la cadena "[object Object]". La posición 0 es [, que parece el inicio de un arreglo, así que los motores más antiguos informaban que fallaba en la o de la posición 1. Esto ocurre cuando pasas un objeto de JavaScript —en lugar de una cadena JSON— a JSON.parse, forzando una conversión implícita a cadena:
const data = { name: "Alice" };
JSON.parse(data); // data se convierte en "[object Object]"; lanza SyntaxError: "[object Object]" is not valid JSON
El V8 actual cita directamente la cadena convertida en lugar de nombrar el carácter o. El valor ya estaba analizado. Úsalo directamente, o si tu intención era hacer una copia profunda, usa structuredClone(data) en lugar de un ciclo stringify/parse.
Unexpected end of JSON input
El analizador se quedó sin caracteres antes de que el JSON estuviera completo. Los dos casos habituales son una cadena vacía (JSON.parse("")) y una respuesta truncada: una solicitud de red interrumpida o un archivo escrito solo parcialmente. Registra primero la longitud de la cadena en bruto; si es 0, el error está antes del analizador, no en tu JSON.
Un flujo de trabajo fiable para depurar JSON
Cuando te encuentras con un error de análisis y el archivo tiene más de unas pocas líneas, mirar fijamente el texto en bruto no es productivo. Aquí tienes un flujo de trabajo que funciona de forma consistente:
-
Pega el JSON en el JSON Formatter. Te mostrará la ubicación exacta del error con un número de línea y una descripción de lo que salió mal.
-
Observa la posición informada. El error suele estar en la posición que informa el analizador, o justo antes. A veces, el error real se encuentra unas líneas antes: por ejemplo, una coma faltante en la línea 10 podría no provocar un error hasta que el analizador llega a la línea 11.
-
Comprueba las cinco causas principales enumeradas arriba. En la práctica, las comas finales y las comillas simples representan la mayoría de los errores de análisis del mundo real.
-
Si el archivo fue generado por código, revisa el paso de serialización. ¿Estás usando
JSON.stringify()o una función equivalente? Construir cadenas JSON a mano con concatenación de cadenas es una fuente habitual de errores. -
Si el archivo se descargó o se recibió desde una API, comprueba la codificación. Los problemas de BOM, las discrepancias en la codificación de caracteres y las respuestas truncadas producen errores de análisis.
Cuando el JSON proviene de una llamada a fetch, lee el texto en bruto y el estado antes de analizar. Este único patrón detecta páginas de error HTML, cuerpos vacíos y respuestas truncadas en un solo lugar:
const response = await fetch("/api/data");
const raw = await response.text(); // lee como texto primero, no response.json()
if (!response.ok) {
console.error(`HTTP ${response.status}:`, raw.slice(0, 200));
} else if (!raw) {
console.error("Cuerpo de la respuesta vacío"); // el clásico "Unexpected end of JSON input"
} else {
try {
const data = JSON.parse(raw);
} catch (e) {
console.error("Fallo al analizar JSON:", e.message, raw.slice(0, 200));
}
}
Errores de análisis en distintos entornos
Los mensajes de error varían según la plataforma, lo que puede dificultar la búsqueda de soluciones.
| Entorno / runtime | Mensaje de error típico | Qué te indica |
|---|---|---|
| Chrome / Node.js (V8) | Unexpected token '<', "<!DOCTYPE html>" is not valid JSON | Un < inicial significa que el servidor devolvió una página HTML en lugar de JSON: revisa la pestaña de red |
| Firefox (SpiderMonkey) | SyntaxError: JSON.parse: unexpected character | MDN documenta los errores de JSON.parse() en este formato JSON.parse: <motivo> (JSON_bad_parseSe abre en una pestaña nueva). La referencia no indica a qué motor corresponde cada redacción, así que trata esto como el formato documentado y no como una cadena confirmada directamente contra SpiderMonkey |
| Python | json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 3 column 5 | Da tanto el número de línea como el de columna |
| Java (Jackson) | JsonParseException: Unexpected character ('}' (code 125)): was expecting double-quote to start field name | Detallado, pero específico sobre lo que esperaba frente a lo que encontró |
Si ves un mensaje así en el navegador (la forma actual de V8 Unexpected token '<', "<!DOCTYPE html>" is not valid JSON, la anterior Unexpected token < in JSON at position 0, o la forma JSON.parse: unexpected character en Firefox), el servidor casi con toda seguridad devolvió una página de error HTML (una página 404 o 500) en lugar de JSON. Sospecha de la URL de la solicitud o del código de estado, no de la sintaxis de tu JSON.
Cómo prevenir los errores de análisis desde el principio
En lugar de corregir los errores a posteriori, unos cuantos hábitos pueden eliminar la mayoría de los errores de análisis de JSON:
- Usa
JSON.stringify()para producir JSON, no la concatenación de cadenas. Esto se aplica a todos los lenguajes: utiliza el serializador integrado. - Configura tu editor para validar JSON al guardar. VS Code, IntelliJ y Sublime Text tienen validación de JSON integrada o disponible como complementos.
- Añade un paso de linting a tu pipeline de CI. Una simple comprobación con
python -m json.tool < config.jsondetectará archivos mal formados antes de que lleguen a producción. - Cuando edites JSON a mano, usa una herramienta con validación en tiempo real. El JSON Formatter valida a medida que escribes y muestra los errores de inmediato.
Ten cuidado con las herramientas en línea que no controlas: pegar datos de trabajo en un conversor no confiable puede exponer información sensible del archivo. Consulta ¿son seguros los conversores en línea? para saber cómo distinguir cuáles procesan los datos localmente. El JSON Formatter de FormatArc corre por completo en tu navegador y nunca sube tus datos.
Para saber más sobre cómo escribir JSON limpio, consulta nuestros consejos de formato de JSON y la guía de sintaxis de JSON. Si te topas con errores de análisis al depurar respuestas de API con curl, nuestra guía para imprimir de forma legible la salida JSON de curl muestra cómo detectar respuestas mal formadas en la terminal antes de que lleguen a tu código.
Cuándo JSON no es el formato adecuado
Si te encuentras peleando con las limitaciones de JSON con regularidad —queriendo comentarios, necesitando cadenas multilínea o lidiando con configuraciones anidadas complejas—, quizá valga la pena considerar YAML como alternativa. YAML admite comentarios, gestiona el texto multilínea con naturalidad y suele ser más legible para los archivos de configuración.
El inconveniente es que YAML es sensible a la indentación y tiene su propio conjunto de trampas (la coerción implícita de tipos, por ejemplo). Pero para archivos de configuración donde las personas necesitan leer y editar el contenido, YAML suele ser la opción más práctica. Siempre puedes convertir entre ambos formatos cuando lo necesites: consulta nuestra guía sobre las diferencias entre YAML y JSON para una comparación más profunda.
Para terminar
Los errores de análisis de JSON son molestos, pero predecibles. Las mismas cinco o seis causas explican la gran mayoría de los casos:
- Comas finales
- Comillas simples
- Claves sin comillas
- Comentarios
- Caracteres BOM
- Corchetes descompensados
Familiarízate con estos patrones y corregirás la mayoría de los errores de análisis en segundos. Y cuando el archivo sea demasiado grande o demasiado complejo para depurarlo a simple vista, pégalo en el JSON Formatter y deja que haga el trabajo. Si quieres formatear JSON automáticamente directamente en la pestaña del navegador, echa un vistazo a nuestra comparación de extensiones de Chrome para formatear JSON.

