Validar un JSON es comprobar que se puede leer y que llega tal cual
JSON sigue la sintaxis que fijan RFC 8259 y ECMA-404. Los objetos van entre llaves { }, los arrays entre corchetes [ ], las claves y las cadenas entre comillas dobles, y un valor solo puede ser una cadena, un número, true, false, null, un objeto o un array. Si un solo carácter se sale de estas reglas, el programa que lo recibe no puede leer el documento entero. El JSON.parse de JavaScript lanza un SyntaxError por una coma final o por unas comillas simples.
Este validador lee el texto que pegas con la sintaxis estándar, sin concesiones. Si la sintaxis falla, te muestra la línea y la columna donde se detuvo la lectura, las líneas de alrededor y el punto donde se abrió el paréntesis que quedó sin cerrar. Las notaciones habituales en configuraciones editadas a mano o en texto copiado de otros lenguajes (comentarios, comas finales, comillas simples, claves sin comillas, True, etc.) se agrupan para poder arreglarlas automáticamente. Si la sintaxis es correcta, ves la estructura en un árbol que se pliega y se despliega, y al elegir un valor aparecen su ruta y el espacio que ocupa.
Aunque la sintaxis sea correcta, el programa que lo recibe puede cambiar el valor. Cuando una clave aparece dos veces, la mayoría de los programas pierden el valor anterior, y un entero grande como 9007199254740993 lo lee JavaScript como 9007199254740992. Estos casos se separan de los errores y se reúnen más abajo en la lista de avisos.
Cuándo conviene validar y desplegar un JSON
- Al revisar la respuesta de una API: si la respuesta llega en una sola línea larguísima, cuesta saber qué valor está dónde. Pégala para verla como árbol y pulsa un valor para copiar su ruta, por ejemplo
$.items[2].price. - Después de editar un archivo de configuración: en archivos que se editan a mano, como package.json, tsconfig.json o los ajustes de VS Code, basta una coma que falte para que el programa no arranque. Si lo pegas aquí antes de guardar, te dice en qué línea está el fallo. Si el archivo admite comentarios, como tsconfig.json, el arreglo automático puede crear una copia sin comentarios para pasársela a otra herramienta.
- JSON copiado de registros o chats: el texto que ha pasado por una aplicación de mensajería o un procesador de textos puede traer comillas tipográficas, espacios especiales de una página web, o comillas simples y True como en la salida de Python. A simple vista esos caracteres no se distinguen, así que la herramienta los señala con su posición.
- Para encontrar por qué pesa tanto una respuesta: el mapa de peso dibuja cada valor del objeto o array elegido con un área proporcional a sus bytes. Un campo con una miniatura en base64 o un array que repite el mismo contenido se ve de un vistazo.
- Antes de enviarlo a otro sistema: los enteros grandes, como números de pedido o identificadores de tuits, las claves duplicadas en un mismo objeto y los escapes de emoji sin pareja pasan la comprobación de sintaxis, pero cambian en el destino. Mira antes la lista de avisos.
Cómo se usa
- Pega el JSON en el cuadro de texto, o abre un archivo .json con «Abrir archivo» o soltándolo encima. La comprobación se hace en cuanto dejas de escribir, y con Ctrl+Intro (⌘+Intro en Mac) se repite al instante.
- Si hay errores, debajo aparecen el diagnóstico y el arreglo automático. Si pulsas «Ir al error» en la barra de estado, el cursor se coloca en ese carácter del cuadro de texto. Si solo quedan notaciones que se pueden arreglar automáticamente, «Arreglar N puntos y pasarlos al texto» lo hace de una vez, y con Deshacer en la barra de estado recuperas el original.
- Si la sintaxis es correcta, elige un valor en el árbol de la izquierda. Con el triángulo o con doble clic se despliegan y se pliegan las ramas, y también puedes moverte con las flechas del teclado. Si mueves el cursor en el cuadro de texto, el árbol te sigue hasta ese valor.
- En el panel de la derecha, elige el formato de ruta (JSONPath, JavaScript, Python, jq o JSON Pointer) y pulsa «Copiar ruta». «Copiar valor» copia solo el valor elegido como JSON con sangría de 2 espacios (si es una cadena, el texto sin comillas).
- Con los botones de debajo del cuadro de texto puedes ordenarlo con sangría de 2 o 4 espacios o comprimirlo en una línea, y luego copiarlo o guardarlo como archivo .json. Al ordenar, los números se quedan tal como los escribiste y las claves duplicadas no se borran.
Mensajes de error y cómo arreglarlos
Si pegas en este validador una de las entradas de la tabla, obtienes el mensaje de la columna central. La posición señala el carácter en el que se detuvo la lectura. La única excepción es la coma que falta: señala el lugar donde debería ir la coma, justo después del valor anterior. Olvidar una coma al final de una línea es el descuido más frecuente, y es más fácil de encontrar si se muestra el final de la línea de arriba que la primera letra de la siguiente.
| Entrada de ejemplo | Mensaje de este validador | Cómo arreglarlo |
|---|---|---|
[1, 2, 3,] | Hay una coma después del último elemento | Borra la coma que va antes del paréntesis de cierre |
{"a": 1 "b": 2} | Falta una coma entre elementos | Pon una coma justo después del 1 |
{'a': 1} | Las cadenas deben ir entre comillas dobles | Cambia 'a' por "a" |
{a: 1} | Esta clave no lleva comillas dobles: a | Escribe la clave como "a" |
{"a": 1, /* nota */ "b": 2} | JSON no admite comentarios | Borra el comentario |
{"ok": True} | Es notación de Python, no un valor JSON: True | Escribe true en minúsculas |
{"avg": NaN} | JSON no tiene este valor: NaN | Cámbialo por null o por una cadena |
{"zip": 04001} | Un número no puede llevar ceros a la izquierda: 04001 | Escríbelo como cadena, por ejemplo "04001" |
["primera línea↵segunda línea"] | Hay un salto de línea dentro de una cadena | Escribe el salto de línea como \n |
{"path": "C:\Users\lucia"} | Esta secuencia de escape no existe en JSON: \U | Escribe la barra invertida dos veces, como \\ |
{"data": [1, 2 | El documento terminó con un paréntesis sin cerrar | Comprueba si se cortó; si de verdad termina ahí, añade ]} |
{"a": 1}↵{"a": 2} | Hay más texto después de que terminara el valor JSON | Agrupa los objetos en un array o trátalo como JSONL |
{“a”: 1} | Son comillas tipográficas, no rectas: “ | Sustitúyelas por unas comillas dobles rectas " |
Si el documento termina con paréntesis abiertos, el diagnóstico muestra los caracteres de cierre que faltan al final, de dentro hacia fuera. Para {"data": [1, 2 son ]}. Pero si la respuesta se cortó al copiarla de un registro o de la pantalla, faltan los datos posteriores, así que es mejor volver a pedir la respuesta original que añadir paréntesis solo para que pase la sintaxis.
Qué cambia el arreglo automático y qué deja como está
El arreglo automático convierte en JSON estándar las notaciones que vienen de formatos ampliados como JSON5 y JSONC, de código Python y JavaScript o de procesadores de textos. Mantiene la disposición de las líneas y la sangría, cambia solo los caracteres afectados y borra la línea entera si solo contenía un comentario. El botón «Arreglar N puntos y pasarlos al texto» aparece únicamente cuando el resultado arreglado vuelve a pasar la comprobación estricta. Si después de arreglar seguirían quedando otros errores, en lugar del botón te indica que empieces por esos.
| Notación que se arregla | Entrada | Resultado del arreglo automático |
|---|---|---|
| Comentarios | {"a": 1 /* memo */} | {"a": 1 } |
| Comas finales | [1, 2, 3,] | [1, 2, 3] |
| Comas que faltan | {"a": 1 "b": 2} | {"a": 1, "b": 2} |
| Cadenas con comillas simples | {'name': 'it\'s'} | {"name": "it's"} |
| Comillas tipográficas | {“name”: “Lucía”} | {"name": "Lucía"} |
| Claves sin comillas | {name: "Lucía", 2024: true} | {"name": "Lucía", "2024": true} |
| Valores de Python y en mayúsculas | [True, False, None, NULL] | [true, false, null, null] |
| NaN, Infinity, undefined | [NaN, Infinity, -Infinity, undefined] | [null, null, null, null] |
| Números como +1, .5, 5., 0x1F | [+1, .5, 5., 0x1F] | [1, 0.5, 5.0, 31] |
| Saltos de línea y tabuladores en cadenas | ["primera línea↵segunda línea", "a→b"] | ["primera línea\nsegunda línea", "a\tb"] |
| Espacio especial (NBSP) | {"a":⍽1} | {"a": 1} |
| BOM al principio | [BOM]{"a": 1} | {"a": 1} |
Cambiar NaN, Infinity y undefined por null altera el significado. Los números de JSON no incluyen el infinito ni NaN, así que null es el único hueco que ofrece el estándar, pero si el programa que lo recibe tiene que distinguir entre «sin valor» y «NaN», es mejor usar una cadena. Un número hexadecimal solo se pasa a decimal si no supera 2⁵³−1.
Lo siguiente no se arregla a propósito. En un número con ceros a la izquierda (04001), la herramienta no puede saber si debe ser texto, como un código postal, o un número. En las comas dobles de [1,,2] no puede saber si se quería poner un valor vacío, y un documento cortado no se puede reconstruir. JSONL, con un objeto por línea, no es algo que arreglar sino otro formato, así que usa un conversor de array JSON a JSONL. Tampoco se tocan los elementos de un array sin coma en la misma línea ([1 -2], ["a" "b"]): en Python o JavaScript eso resta o une las cadenas, así que añadir una coma cambiaría el significado. Solo se insertan comas en los saltos de línea y antes de las claves de un objeto.
Cinco notaciones de ruta
Cuando eliges un valor en el árbol, la ruta hasta él se escribe en cinco notaciones. El mismo valor se escribe distinto según dónde lo uses. JSONPath se usa en Postman, en muchas herramientas de pruebas de API y en consultas de bases de datos. Las notaciones de JavaScript y Python van en el código, jq en la línea de comandos y JSON Pointer en JSON Patch (RFC 6902) o en el $ref de JSON Schema. En las notaciones de JavaScript y Python, data es la variable que contiene el JSON ya leído.
| JSONPath | JavaScript | Python | jq | JSON Pointer |
|---|---|---|---|---|
$.items[2].options.gift_wrap | data.items[2].options.gift_wrap | data["items"][2]["options"]["gift_wrap"] | .items[2].options.gift_wrap | /items/2/options/gift_wrap |
$.headers['x-request-id'] | data.headers["x-request-id"] | data["headers"]["x-request-id"] | .headers["x-request-id"] | /headers/x-request-id |
$.dirección.código_postal | data.dirección.código_postal | data["dirección"]["código_postal"] | .["dirección"]["código_postal"] | /dirección/código_postal |
$['a/b']['m~n'] | data["a/b"]["m~n"] | data["a/b"]["m~n"] | .["a/b"]["m~n"] | /a~1b/m~0n |
$ | data | data | . | cadena vacía |
Cada notación admite un conjunto distinto de claves tras el punto (.). El estándar JSONPath (RFC 9535) permite en la notación con punto letras, guiones bajos y cualquier carácter desde U+0080, así que una clave con tilde como dirección se escribe $.dirección.código_postal. jq solo admite letras, dígitos y guiones bajos tras el punto, por lo que una clave con tilde o con guion se encierra entre corchetes, como en .["dirección"]. JavaScript sigue sus reglas de identificadores, de modo que una clave con tilde funciona con punto, mientras que una clave con guion como x-request-id necesita corchetes. JSON Pointer une las claves con /, así que un ~ dentro de una clave pasa a ~0 y una / pasa a ~1, y el documento entero es la cadena vacía.
Cuando la sintaxis es correcta pero el valor cambia
Números grandes. La sintaxis de JSON no limita el número de dígitos, pero RFC 8259 señala que la mayoría de los programas tratan los números como IEEE 754 binary64 (coma flotante de doble precisión) y que los enteros se leen igual en todas partes solo de −(2⁵³−1) a 2⁵³−1. Un entero mayor, o un decimal con demasiadas cifras significativas, pasa a ser el valor binary64 más cercano. Este validador compara las cifras significativas que escribiste con el valor que se lee y avisa solo de los números que cambian.
| Número escrito en el JSON | Valor que lee JavaScript | Este validador |
|---|---|---|
9007199254740991 | 9007199254740991 | Sin cambios (el mayor entero seguro) |
9007199254740993 | 9007199254740992 | Pérdida de precisión |
1234567890123456789 | 1234567890123456800 | Pérdida de precisión |
0.1234567890123456789 | 0.12345678901234568 | Pérdida de precisión |
1.10 | 1.1 | Sin cambios (el mismo valor; las cifras también se conservan al ordenar) |
1e400 | Infinity | Número fuera de rango (Python lo lee como inf) |
1e-400 | 0 | Número que pasa a ser 0 |
Los enteros grandes con los que no se calcula, como los números de pedido o de socio, es más seguro intercambiarlos como cadenas, por ejemplo "1234567890123456789". RFC 7493 (I-JSON) también recomienda poner en cadenas los números que necesitan más rango o precisión que binary64.
Claves duplicadas. RFC 8259 dice que las claves de un objeto SHOULD ser únicas y añade que, cuando se repiten, unos programas se quedan solo con el último valor, otros dan error y otros los pasan todos, así que el comportamiento no se puede predecir. El JSON.parse de JavaScript y el json de Python usan el valor posterior. Este validador no bloquea las claves duplicadas como errores sino que las marca como aviso, y cuando eliges una de ellas en el árbol muestra un botón que lleva a la clave anterior con el mismo nombre.
Sustitutos sueltos. Un carácter por encima de U+FFFF, como un emoji, es una pareja de dos escapes como \ud83d\ude00. Si se cortó por la mitad y solo queda \ud83d, la sintaxis sigue pasando, pero el resultado es un carácter que no se puede convertir a UTF-8, y en el destino se ve basura o se produce un error. I-JSON no permite estos caracteres.
BOM. Editores como el Bloc de notas a veces ponen un BOM (U+FEFF) al principio del archivo. RFC 8259 dice que al enviar JSON NO se debe añadir un BOM (MUST NOT) y que quien lee puede ignorarlo (MAY). Aun así, el JSON.parse de JavaScript y el json.loads de Python (con una cadena) tratan el BOM como un error. Este validador se salta el BOM y sigue leyendo, lo marca como aviso y lo quita del resultado cuando ordenas o comprimes.
Orden de las claves. En principio, el orden de las claves de un objeto JSON no significa nada, pero el orden en que las escribiste importa cuando lo lee una persona. Un objeto de JavaScript coloca delante de las demás las claves con forma de entero, como "2024" (OrdinaryOwnPropertyKeys de ECMAScript). Por eso este validador no usa el JSON.parse del navegador y dibuja el árbol en el orden escrito con su propio analizador.
Cómo leer el mapa de peso
El mapa de peso mide los bytes UTF-8 que ocupa en el texto cada valor situado justo debajo del objeto o array elegido y reparte el área en proporción. En un objeto cuenta el nombre de la clave, el valor y el espacio entre ambos. Las celdas más anchas se colocan primero, lo más cuadradas posible, hasta un máximo de 30, y los valores que no llegan al 0,4 % del total se agrupan en una sola celda rayada de «más». Los colores de las celdas coinciden con los del texto del árbol según el tipo (objeto, array, cadena, número, booleano, null).
Pulsa una celda para elegir ese valor. Si es un objeto o un array, se despliega en el árbol y el mapa entra un nivel. Pulsa la ruta de ubicación que hay encima del mapa (Todo › items › 0) para volver a salir. En el ejemplo «Respuesta de API de pedidos», items, que contiene tres productos, es lo más ancho, y al entrar se ve que el producto con más opciones ocupa más sitio. En respuestas reales suelen aparecer como celdas anchas las imágenes en base64, las descripciones largas que se repiten cada vez y los campos de depuración que ya no se usan.
Errores frecuentes
- Confundir un objeto de JavaScript con JSON:
{name: 'a', list: [1, 2,],}escrito en el código es válido en JavaScript, pero no es JSON. Hay que poner las claves y las cadenas entre comillas dobles y borrar las comas finales. El arreglo automático resuelve las tres cosas de una vez. - Copiar tal cual la salida de Python: el resultado de
print(dict)usa comillas simples, True y None, como en{'ok': True, 'x': None}. Si necesitas JSON, imprime conjson.dumps(). Si ya lo copiaste, el arreglo automático puede convertirlo. - Barras invertidas en rutas de Windows: el
\Ude"C:\Users"no es un escape de JSON, así que da error. Escribe la barra invertida dos veces, como"C:\\Users", o usa barras normales, como"C:/Users". Las carpetas cuyo nombre empieza por\no\tse convierten en un salto de línea o un tabulador sin dar ningún error, así que hay que andar con más cuidado. - Números frente a texto con aspecto de número:
42y"42",falsey"false"son valores distintos. En el árbol los números salen en morado y las cadenas en marrón con comillas, así que puedes comprobar que el tipo es el que querías. - Comprobar un JSONL como si fuera un solo documento: un texto con un objeto por línea, como un archivo de registro, da el error «Hay más texto después de que terminara el valor JSON» tras el primer objeto. Compruébalo línea por línea o conviértelo en un array.
- Creer que pasar la sintaxis es validar los datos:
{"age": -5}y{"date": "2026-02-30"}son JSON válido. Las claves obligatorias, los rangos de valores y la existencia de una fecha hay que comprobarlos con JSON Schema o con la validación del sistema que lo recibe.
Límites y precauciones
- Se comprueban textos de hasta 5 MB (5 242 880 bytes). Los archivos se leen como UTF-8 (con o sin BOM) o UTF-16 con BOM. El anidamiento se lee hasta 500 niveles.
- El árbol dibuja hasta 3000 filas de una vez, y los arrays con muchos elementos se despliegan de 200 en 200 con «Mostrar más». La búsqueda cuenta hasta las primeras 10 000 coincidencias.
- Los números de columna cuentan puntos de código. Un carácter que ocupa dos unidades en UTF-16, como un emoji, es una sola columna, así que el número puede diferir de la «position» de un mensaje de error del navegador, que cuenta unidades UTF-16.
- El arreglo automático solo cambia la notación. Algunos arreglos alteran el significado, como convertir NaN e Infinity en null, así que lee la lista antes de usarlo. Los números con ceros a la izquierda, las comas dobles y los documentos cortados no se arreglan.
- No valida con JSON Schema, no compara dos JSON ni ordena claves. Para profundizar en ordenar con sangría y comprimir, usa un formateador y minificador de JSON.
Fuentes
- 01IETF — RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format§2 gramática, §4 los nombres SHOULD ser únicos, §6 binary64 e interoperabilidad de ±(2⁵³−1), §8.1 no añadir BOM y quien lee puede ignorarlo, §8.2 sustitutos sueltos — comprobado el 2026-10-22
- 02Ecma International — ECMA-404: The JSON data interchange syntaxEl estándar de la sintaxis JSON (el espacio en blanco es solo tabulador, salto de línea, retorno de carro y espacio)
- 03IETF — RFC 7493: The I-JSON Message Format§2.1 sin sustitutos ni no caracteres, §2.2 cadenas recomendadas para números que superan binary64, §2.3 nombres duplicados MUST NOT
- 04IETF — RFC 9535: JSONPath: Query Expressions for JSON§2.5.1.1 member-name-shorthand (letras, guion bajo, caracteres desde U+0080), selectores de nombre con comillas simples y dobles
- 05IETF — RFC 6901: JavaScript Object Notation (JSON) PointerRutas unidas con /, ~ como ~0 y / como ~1, la cadena vacía para el documento entero
- 06jq Manual.foo solo para claves de letras, dígitos y guion bajo; las demás, como ."foo" o .["foo"]
- 07Documentación de Python — json: JSON encoder and decoder'Repeated Names Within an Object': de un mismo nombre solo se conserva el último valor; NaN e Infinity se aceptan por defecto
- 08The JSON5 Data Interchange Format§1.1 ampliaciones respecto a JSON: comentarios, comas finales, comillas simples, claves como identificadores, hexadecimal, punto decimal inicial y final, signo +, NaN e Infinity
- 09MDN — JSON.parse()Las comas finales y las comillas simples dan SyntaxError
- 10MDN — Number.MAX_SAFE_INTEGEREl mayor entero que JavaScript representa con exactitud, 2⁵³−1 = 9 007 199 254 740 991
- 11ECMAScript Language Specification — OrdinaryOwnPropertyKeys§10.1.11.1 las claves con forma de índice de array se listan primero, en orden numérico
Preguntas frecuentes
¿Por qué la línea y la columna del error no coinciden con el lugar donde está el fallo?
La posición que se muestra es donde el analizador no pudo seguir leyendo. Si falta una coma, señala el lugar donde debería ir, justo después del valor anterior, pero si faltan unas comillas de cierre la cadena sigue hasta la línea siguiente y el analizador se detiene después. Mirar las líneas de alrededor y el «paréntesis abierto o inicio de la cadena» del diagnóstico ayuda a encontrar la causa.
¿Qué arregla el arreglo automático?
Trata 12 tipos de notación: comentarios, comas finales, comas que faltan entre líneas, cadenas con comillas simples y con comillas tipográficas, claves sin comillas, True, False, None y TRUE y NULL en mayúsculas, NaN, Infinity y undefined (que pasan a null), números como +1, .5, 5. y 0x1F, saltos de línea y tabuladores dentro de cadenas, espacios especiales y un BOM al principio. Mantiene la disposición de las líneas, cambia solo esos caracteres y el botón aparece únicamente si el resultado arreglado vuelve a pasar la comprobación estricta.
¿Puedo comprobar un archivo JSONC o JSON5 con comentarios?
Este validador comprueba JSON estándar (RFC 8259), así que los comentarios y las comas finales se muestran como errores. Con el arreglo automático, en cambio, puedes quitar comentarios, comas finales, comillas simples y claves sin comillas para obtener JSON estándar. Si el archivo original va a seguir siendo JSONC, usa el resultado arreglado como una copia para pasársela a otro programa.
¿Por qué un número grande cambia a algo como 9007199254740992?
JavaScript y muchos otros programas leen los números de JSON como coma flotante IEEE 754 binary64. Ese formato guarda enteros con exactitud solo hasta ±(2⁵³−1), es decir, 9 007 199 254 740 991, así que un entero mayor, o un decimal con más de 17 cifras significativas, pasa al valor más cercano. Este validador muestra en los avisos los números que cambian, junto con el valor que lee JavaScript. Para identificadores es más seguro enviarlos como cadenas.
¿Qué pasa si una misma clave aparece dos veces en un objeto?
RFC 8259 solo dice que las claves SHOULD ser únicas y señala que el comportamiento ante repeticiones varía según el programa. JSON.parse de JavaScript y json de Python usan el último valor y descartan el anterior. Este validador no lo bloquea como error de sintaxis sino que lo marca como aviso, y el árbol y el resultado ordenado conservan los dos valores.
¿En qué se diferencian las rutas JSONPath y jq?
JSONPath (RFC 9535) empieza por $ y se escribe como $.items[0].name, y las claves con caracteres que no son ASCII, como las que llevan tilde, también pueden usar la notación con punto. jq empieza por . y se escribe como .items[0].name, pero la notación con punto solo vale para claves de letras, dígitos y guiones bajos, así que una clave con tilde o con guion se escribe .["clave"]. JSON Pointer (RFC 6901) une las claves con / como en /items/0/name y escribe ~ como ~0 y / como ~1.
¿En qué se basa el tamaño del mapa de peso?
Para cada valor situado justo debajo del objeto o array elegido, mide los bytes UTF-8 que ocupa en el texto (con el nombre de la clave y los espacios) y reparte el área en proporción. Dibuja hasta 30 de las celdas más grandes y agrupa el resto, muy pequeño, en una sola celda de «más». Úsalo para descubrir por qué pesa tanto una respuesta de API y qué array ocupa el espacio.
¿El JSON que escribo se envía a un servidor o se guarda?
No. El texto pegado y los archivos abiertos se comprueban y se convierten solo dentro de este navegador, y no se envía ni se guarda nada en ningún servidor. La dirección tampoco contiene tu contenido, así que, después de comprobar una respuesta con tokens o datos personales, basta con cerrar la pestaña o pulsar Borrar.