Bloques morados conectados con NO, 010, marcas de verificación, ochos y llaves duplicadas que ilustran errores de conversión en YAML.

YAML parece una lista de cadenas simples, así que es fácil suponer que el parser devuelve exactamente lo que escribiste. No lo hace. Los errores de YAML de esta guía vienen todos del mismo mecanismo: YAML asigna un tipo a cada escalar sin comillas mediante una tabla de resolución, y qué tabla se aplica depende de la versión de YAML que implemente el parser.

Analizado el 2026-10-09, este documento de tres líneas produce dos resultados distintos:

countries: [GB, IE, FR, DE, NO]
flag: yes
code: 010
PyYAML 6.0.2   {'countries': ['GB', 'IE', 'FR', 'DE', False], 'flag': True, 'code': 8}
js-yaml 5.4.2  {'countries': ['GB', 'IE', 'FR', 'DE', 'NO'], 'flag': 'yes', 'code': 10}
yaml 2.9.1     {'countries': ['GB', 'IE', 'FR', 'DE', 'NO'], 'flag': 'yes', 'code': 10}

Ninguno de los dos resultados es un error del archivo. PyYAML implementa las reglas de YAML 1.1, donde NO es un booleano y un cero inicial significa octal. js-yaml y el paquete yaml siguen el core schema de YAML 1.2, donde ninguna de las dos cosas se cumple. El resto de la guía repasa las seis trampas detrás de esa diferencia y cómo detectarlas antes de que lleguen a producción.

01Por qué YAML cambia tus datos sin dar error

Cada nodo de un documento YAML recibe una etiqueta, y un escalar simple sin etiqueta explícita se resuelve comparándolo con una lista de expresiones regulares. La especificación YAML 1.2.2 define esa lista en el core schema: null, booleanos, enteros, flotantes y cadenas, en ese orden de especificidad.

El core schema es deliberadamente estrecho: solo reconoce true, True, TRUE, false, False y FALSE como booleanos. YAML 1.1 era mucho más permisivo, y su repositorio de tipos independientes del lenguaje incluye y, Y, yes, Yes, YES, n, N, no, No, NO, true, True, TRUE, false, False, FALSE, on, On, ON, off, Off y OFF como formas de escribir un booleano.

Esa historia explica por qué el mismo archivo se comporta distinto entre lenguajes. Un parser no solo tiene que adivinar tu intención: tiene que hacerlo con la versión de la especificación que su autor eligió hace años. Cuando aparece un fallo de YAML, la primera pregunta útil no es «qué dice el archivo», sino «qué resolvió este parser».

Un documento YAML válido no es un archivo de configuración correcto.

La validación responde si el documento se puede analizar. No dice nada sobre si un escalar sin comillas se resolvió con el tipo que querías, y de ahí sale cada una de las trampas siguientes.

02Trampa 1: el Norway problem

El Norway problem es el ejemplo canónico, y tiene historia. El proyecto StrictYAML documenta una lista de países que funcionaba bien para GB, IE, FR y DE, y fallaba en silencio para Noruega: el código de dos letras NO es también la forma en que YAML 1.1 escribe false.

countries:
  - GB
  - IE
  - FR
  - DE
  - NO

Leído por un parser de YAML 1.1, el último elemento es el booleano False, no la cadena "NO". El código que busca un país por su código falla en una búsqueda que debería haber funcionado, y nada en los logs apunta al archivo.

La solución es poner comillas en cualquier escalar que deba seguir siendo texto, o indicar el tipo de forma explícita:

countries:
  - GB
  - IE
  - FR
  - DE
  - "NO"
strict_code: !!str NO

Los códigos de país son solo el caso visible. La misma trampa alcanza abreviaturas de estados, indicadores yes/no que querías leer como texto y cualquier identificador corto que coincida con una forma booleana.

03Trampa 2: tabuladores en la indentación

YAML es sensible a los espacios en blanco, y el tabulador es el primer error clásico. La especificación YAML 1.2.2 exige que los tabuladores no se usen en la indentación, así que no es una rareza de una librería concreta.

Los mensajes de error cambian según el parser, y por eso conviene buscar el texto exacto:

PyYAML 6.0.2   ScannerError: while scanning for the next token
               found character '\t' that cannot start any token (line 2, column 1)
js-yaml 5.4.2  YAMLException: tab characters must not be used in indentation (2:1)
yaml 2.9.1     YAMLParseError: Tabs are not allowed as indentation at line 2, column 1

Un tabulador dentro de una cadena entre comillas es un dato y sigue siendo legal. La regla habla de la indentación. Configura tu editor para insertar espacios en los archivos .yml y .yaml, y deja que un formateador normalice el bloque si lo pegaste desde un chat o un log.

04Trampa 3: claves duplicadas y claves de fusión

Un mapping YAML se define como un conjunto de pares clave/valor con la restricción de que cada clave sea única, y las claves no únicas aparecen como uno de los fallos de carga de la especificación. Aun así, las implementaciones no coinciden en cuánto ruido hacen:

Parsera: 1 y después a: 2
PyYAML 6.0.2Carga {'a': 2}, conservando el último valor en silencio
js-yaml 5.4.2YAMLException: duplicated mapping key (2:1)
yaml 2.9.1YAMLParseError: Map keys must be unique at line 2, column 1

La clave de fusión es lo mismo con más radio de explosión. << viene del tipo merge de YAML 1.1 y cada implementación la trata a su manera: PyYAML fusiona el mapa anclado dentro del hijo, mientras que js-yaml 5.4.2 y yaml 2.9.1 dejan una clave << literal cuyo valor es el mapa padre. Un archivo hijo puede acabar con una clave inesperada en lugar de heredar los valores, y una clave duplicada puede tapar sin ruido la que un revisor ya había aprobado.

No confíes en las claves de fusión para valores por defecto de seguridad.

Si el mapa padre contiene un valor por defecto seguro y el hijo debería heredarlo, un parser que deja << sin resolver deja a la aplicación sin el valor y sin un error. Fija la versión del parser en CI y comprueba el objeto resuelto, no solo que el archivo se pueda analizar.

05Trampa 4: booleanos y números según la versión

Los booleanos se llevan la atención, pero las reglas numéricas también cambiaron, y no siempre en la misma dirección:

EntradaYAML 1.1YAML 1.2 corePyYAML 6.0.2js-yaml 5.4.2
yesbooleano truecadenaTrue"yes"
onbooleano truecadenaTrue"on"
ybooleano truecadena"y""y"
010entero 8, octalentero 10810
0o10cadenaentero 8"0o10"8
1:30entero 90, base 60cadena90"1:30"
1e3cadenaflotante 1000"1e3"1000

Dos detalles merecen una segunda lectura. El tipo entero de YAML 1.1 usa un cero inicial para el octal y dos puntos para la base 60, así que 1:30 es noventa, no una hora. El patrón de flotante de YAML 1.1 exige un exponente con signo, así que 1e3 se queda como cadena mientras que 1.0E+3 se convierte en flotante: verificado en local con python3 -c "import yaml; print(yaml.safe_load('a: 1.0E+3'))", que imprime {'a': 1000.0}.

Incluso dentro de «YAML 1.1» las implementaciones se pelean: el repositorio de tipos lista y como booleano, pero PyYAML 6.0.2 lo deja como cadena. El nombre de la versión es un punto de partida, no una garantía.

06Trampa 5: versiones, códigos postales e IDs largos

Hay tres campos cotidianos que se rompen de una forma que sobrevive a la revisión de código, porque el texto visible sigue pareciendo correcto en el editor:

  • version: 1.10 carga como el flotante 1.1. El cero final no forma parte de un número, así que desaparece al volver a escribir el archivo y la comparación de versiones toma la dirección equivocada.
  • zip: 01234 carga como el entero 668 en PyYAML y como 1234 en js-yaml. Un cero inicial es octal en YAML 1.1 y decimal en el core schema de 1.2, y ninguna de las dos es la cadena que querías.
  • Un identificador de 20 dígitos como 12345678901234567890 carga como 12345678901234567000 en un parser de JavaScript, porque un number de JS no puede guardar con exactitud todos los enteros de 64 bits. PyYAML conserva el valor completo como entero de Python, así que la misma clave de API funciona en un servicio y falla en otro.

Las fechas son otra frontera entre versiones. PyYAML 6.0.2 resuelve un 2026-10-04 sin comillas como un objeto datetime.date, mientras que js-yaml 5.4.2 lo deja como la cadena "2026-10-04" en la configuración probada aquí. Si tu código espera una cadena y recibe un objeto de fecha, al serializarlo de vuelta a JSON obtendrás otra forma.

La regla que evita los tres casos es simple: pon comillas en identificadores, versiones, códigos y en cualquier valor que quieras comparar como texto. Si un campo debe ser un número, dilo en un schema en lugar de confiar en el resolver.

07Trampa 6: anclas y alias

Las anclas y los alias son el mecanismo de reutilización de YAML: &name marca un nodo, *name inserta una referencia a él, y un documento puede expresar una estructura enorme con muy poco texto. Ahí está también el riesgo. El patrón «billion laughs» anida alias hasta que un archivo pequeño se expande en un objeto gigantesco, y un parser sin límite de expansión puede agotarse con un documento de unos pocos cientos de bytes.

En lenguajes con objetos mutables hay un problema más fino: un alias es una referencia al mismo nodo, no una copia, así que modificar el objeto detrás de *name cambia también todos los lugares donde aparece el ancla. Además, los alias solo apuntan hacia atrás: un alias se refiere a un ancla definida antes, así que una referencia hacia delante falla aunque la estructura parezca obvia.

En archivos de configuración, mantén la reutilización superficial y expande las anclas antes de comparar o revisar. Si dos entornos deben ser distintos, el diff entre documentos expandidos es el único en el que un revisor puede confiar.

08Cómo validar YAML antes de publicarlo

La comprobación de sintaxis atrapa los errores de tabulación y de claves duplicadas de las secciones anteriores. El Validador de YAML de UrsaKit analiza el documento en tu navegador e informa la primera posición en la que no puede continuar.

  1. Pega el documento en el cuadro YAML input.
  2. Pulsa Validate YAML.
  3. Lee el resultado. Un documento válido devuelve el mensaje verde This YAML is valid.; uno roto devuelve This YAML is invalid con la línea, la columna y el mensaje del parser.
  4. Corrige la primera posición señalada y vuelve a validar. Los errores de YAML se encadenan, así que la línea 40 suele ser consecuencia de la línea 12.

El paso que atrapa los tipos implícitos es otro: country: NO pasa la validación porque el documento es válido. Para ver qué resolvió el parser, pasa el mismo texto por YAML a JSON y mira la salida.

{
  "country": false
}

Ese es el momento de añadir comillas. Cuando el documento esté confirmado, usa el Formateador de YAML para normalizar la indentación; reindenta con el ancho que elijas y conserva comentarios y anclas, así que la corrección no te cuesta el rastro de revisión.

SíntomaCausaSolución
NO o yes se convierte en booleanoResolución implícita de booleanos de YAML 1.1Pon comillas o etiqueta con !!str
ScannerError por un carácter invisibleTabulador en la indentaciónUsa espacios y reindenta con el formateador
Una clave gana sin avisarClave duplicada con un parser permisivoAnaliza con js-yaml o yaml en CI
El archivo hijo no hereda los valoresEl parser no admite la clave de fusiónExpande el mapa padre o fija el parser
1.10 se convierte en 1.1Versión leída como número flotantePon comillas en versiones y números de build

09YAML, JSON o TOML: cuál elegir

El cambio de core schema en YAML 1.2 hizo que YAML fuera un superconjunto estricto de JSON y eliminó muchas de las recomendaciones problemáticas de tipos implícitos, pero las reglas antiguas siguen vivas en los parsers anteriores a 1.2 o que lo ignoran. Elige el formato según quién escribe el archivo y cuánto importan los valores:

YAMLJSONTOML
ComentariosSíNoSí
Tipos implícitosSí, según la versiónNoNo
Cadenas multilíneaEscalares de bloqueSolo con escapesCadenas básicas multilínea
ReutilizaciónAnclas y aliasNingunaNinguna
Compatible con JSON1.2 es superconjuntoNativoNo
Ideal paraConfiguración editada por personasPayloads de API y salida de máquinasConfiguración humana con tipos estrictos

Si un valor debe sobrevivir intacto al ciclo completo, guárdalo en JSON o pon comillas en YAML. Si el archivo lo escribe una persona y lo lee una sola aplicación, la flexibilidad de YAML vale la disciplina de citar todo lo que parezca código.

Cuando la configuración tenga que llegar a una API, conviértela y revisa el payload con el Validador de JSON. Para el camino inverso, el conversor JSON a YAML devuelve el JSON escrito por una máquina a un archivo que una persona puede editar.

10Fuentes

Preguntas frecuentes

¿Qué es el Norway problem en YAML?

Es el código de país NO interpretado como el booleano false, porque YAML 1.1 resuelve los escalares sin comillas no y NO como booleanos. El nombre viene de una lista de países en la que Noruega se convirtió en false sin avisar.

¿Por qué YAML dice que yes no es un booleano?

Depende de la versión. YAML 1.1 acepta yes, no, on y off como booleanos, mientras que el core schema de YAML 1.2 solo acepta true, True, TRUE, false, False y FALSE. Un parser de YAML 1.2 deja yes como cadena.

¿Por qué mi YAML falla con un error de tabulación?

La especificación prohíbe los tabuladores en la indentación, así que el parser se detiene en cuanto aparece uno donde debería haber sangría. Configura el editor para insertar espacios en los archivos YAML.

¿YAML permite claves duplicadas?

No. Las claves de un mapping deben ser únicas, y las claves no únicas son uno de los fallos de carga documentados. PyYAML conserva el último valor en silencio, mientras que js-yaml y el paquete yaml lanzan un error, así que el mismo archivo se comporta distinto según el parser.

¿Por qué 1.10 se convierte en 1.1?

Un 1.10 sin comillas se lee como número en coma flotante, y el cero final no aporta valor en un número, así que vuelve a salir como 1.1. Pon comillas en versiones, números de build e identificadores para conservarlos como texto.

¿Por qué mi ID largo perdió los últimos dígitos?

JavaScript no puede representar con exactitud todos los enteros de 64 bits. Un ID de 20 dígitos se redondea al convertirse en number, así que 12345678901234567890 vuelve como 12345678901234567000. Deja los identificadores entre comillas.

¿Un YAML válido siempre es correcto?

No. Un validador responde si el documento se puede analizar, no si el parser resolvió tus valores como esperabas. Un archivo con country: NO es YAML válido y sigue cargando como false.

Volver a los artículos

Artículos relacionados

Herramientas relacionadas

  • Validador de YAML

    Comprueba la sintaxis y señala la línea y la columna del primer error.

  • Formateador de YAML

    Reindenta el documento y conserva comentarios y anclas.

  • YAML a JSON

    Mira los valores que el parser resolvió de verdad, tipos incluidos.

  • Validador de JSON

    Revisa el payload convertido antes de que llegue a una API.

  • JSON a YAML

    Convierte JSON generado por una máquina en un archivo editable.