yaml-cpp acepta en silencio las claves duplicadas en los mapeos YAML y conserva solo el último valor: sin error, sin advertencia, sin ninguna indicación de que los valores anteriores se descartaron. La especificación YAML llama explícitamente indefinido a este comportamiento, pero cada analizador importante toma su propia decisión. Esta guía explica qué hace yaml-cpp, en qué se diferencian otros analizadores, qué escenarios reales producen duplicados y cómo detectarlos antes de que provoquen errores silenciosos de pérdida de datos en producción.
¿Qué son las claves duplicadas en YAML?
Una clave duplicada se produce cuando la misma cadena de clave aparece más de una vez en el mismo nivel dentro de un único mapeo YAML. En un lenguaje como JSON esto también está indefinido, pero es visualmente obvio. En YAML, donde los mapeos abarcan varias líneas y los archivos pueden tener cientos de líneas, las claves duplicadas son fáciles de introducir por accidente y igual de fáciles de pasar por alto en una revisión.
Cómo se ve un duplicado
La forma más simple es una repetición directa: una clave definida al principio de un mapeo y redefinida más abajo, a veces con un valor diferente. Esto ocurre sobre todo por errores de copiar y pegar, refactorizaciones incompletas o la fusión de fragmentos de configuración de distintas fuentes. Los nombres de clave son idénticos byte a byte (misma capitalización, mismos espacios) y simplemente aparecen dos veces en el mismo bloque de mapeo.
- Error de copiar y pegar: se duplica un bloque de claves al añadir una sección nueva basada en una existente
- Renombrado incompleto: se renombra una clave pero no se elimina la original, y ambas quedan en el archivo
- Fusión de configuraciones: se concatenan dos fragmentos YAML y ambos definen la misma clave de nivel superior
- Reversión de comentario: se descomenta una clave sin eliminar el reemplazo activo que está debajo
- Expansión de plantillas: un generador o motor de plantillas emite la misma clave dos veces desde ramas condicionales distintas
Nota
Qué dice realmente la especificación YAML
La especificación YAML 1.2 aborda las claves duplicadas de forma directa e inequívoca: no están permitidas en un mapeo YAML válido. La sección 3.2.1.3 indica que las claves de un mapeo deben ser únicas dentro de ese mapeo. Cualquier documento con claves duplicadas es técnicamente no conforme.
El contenido de un nodo de mapeo es un conjunto no ordenado de pares de nodos clave/valor, con la restricción de que cada una de las claves sea única.
Indefinido no significa análisis inválido
El matiz crítico es que, aunque la especificación considera las claves duplicadas no conformes, no obliga a que los analizadores las rechacen con un error grave. En su lugar, describe el comportamiento como indefinido, lo que significa que cada implementación de analizador es libre de tratar los duplicados como quiera. Por eso yaml-cpp, PyYAML, js-yaml y otros analizadores aceptan duplicados sin lanzar nada, aunque el documento resultante sea técnicamente YAML inválido.
Por qué esto importa en la práctica
Un «comportamiento indefinido» en una especificación significa que tu aplicación depende de un detalle de implementación que podría cambiar entre versiones de la biblioteca. Actualmente yaml-cpp usa «gana el último valor», pero nada en la especificación lo garantiza. Una versión futura podría pasar a «gana el primer valor», lanzar una excepción o devolver un nodo de error, y cualquiera de esos cambios sería conforme a la especificación. El código que depende por accidente del comportamiento de resolución de claves duplicadas es frágil por definición.
Aviso
El comportamiento de yaml-cpp en detalle
yaml-cpp es la biblioteca de análisis YAML para C++ más usada y la opción predeterminada en muchas aplicaciones C++ y motores de videojuegos. Cuando yaml-cpp encuentra una clave duplicada en un mapeo, analiza ambas apariciones pero solo conserva la última en el árbol Node resultante. El valor anterior se sobrescribe y desaparece definitivamente de la estructura analizada.
La regla de «gana el último valor»
En la implementación de yaml-cpp, cada clave de un mapeo se guarda en una lista ordenada de pares clave-valor. Cuando se analiza una clave duplicada, yaml-cpp busca en la lista existente una clave coincidente. Si la encuentra, sustituye el valor almacenado por el nuevo. El nodo del valor anterior se libera. Desde la perspectiva de la aplicación, consultar `node["key"]` devuelve el último valor definido como si solo hubiera existido una definición.
Sin salida de diagnóstico por defecto
yaml-cpp no emite ninguna advertencia, mensaje de registro ni excepción cuando sobrescribe una clave duplicada. El análisis finaliza con un `YAML::Node` que parece completamente normal. No hay ninguna marca que puedas consultar después del análisis para descubrir que se resolvieron duplicados en silencio. La única forma de detectarlos es revisar el texto sin procesar antes de analizarlo, que es exactamente lo que hace un detector dedicado de claves duplicadas.
El comportamiento es coherente entre estilos de mapeo
yaml-cpp aplica «gana el último valor» de forma coherente, independientemente de si el mapeo usa estilo de bloque (claves en líneas separadas) o estilo de flujo con llaves. Los mapeos anidados se gestionan de forma independiente: los duplicados solo se comparan dentro del mismo nivel de mapeo, no en todo el árbol del documento. Una clave que aparece en dos mapeos hermanos a distinta profundidad de anidamiento no se considera duplicada.
Detector de claves duplicadas en YAML
Pega tu documento YAML y encuentra al instante todas las claves duplicadas en cada nivel de anidamiento: informa de los números de línea y de ambos valores en conflicto para que los corrijas antes de que lleguen a yaml-cpp.
Cómo tratan los duplicados otros analizadores
Como la especificación YAML deja indefinido el comportamiento con claves duplicadas, cada ecosistema de analizadores ha tomado su propia decisión. La variación entre lenguajes es lo bastante grande como para que un archivo YAML que pasa en silencio en una canalización falle sin remedio en otra. Conocer el panorama te ayuda a escribir YAML portátil.
| Analizador / Biblioteca | Lenguaje | Comportamiento con claves duplicadas |
|---|---|---|
| yaml-cpp | C++ | Gana el último valor: silencioso, sin advertencia |
| PyYAML | Python | Gana el último valor: silencioso, sin advertencia |
| ruamel.yaml (estricto) | Python | Lanza DuplicateKeyError cuando se configura |
| js-yaml | JavaScript | Gana el último valor: silencioso, sin advertencia |
| gopkg.in/yaml.v3 | Go | Devuelve error: duplicate map key |
| go-yaml v2 | Go | Gana el último valor: silencioso, sin advertencia |
| Psych (por defecto) | Ruby | Lanza Psych::BadAlias / error en versiones recientes |
| SnakeYAML | Java | Gana el último valor: silencioso (configurable) |
| YamlDotNet | C# / .NET | Gana el último valor: silencioso, sin advertencia |
| libfyaml | C | Emite advertencia; comportamiento configurable |
La conclusión práctica es contundente: `yaml.v3` de Go trata los duplicados como errores graves, mientras que yaml-cpp, PyYAML y js-yaml los aceptan en silencio. Un archivo de configuración YAML que funciona en tu aplicación C++ con yaml-cpp puede fallar de inmediato cuando el mismo archivo lo procesa un servicio Go o un linter estricto de Python en una canalización de CI.
Consejo
Escenarios reales que provocan duplicados
La mayoría de las claves duplicadas no son intencionadas. Aparecen por patrones previsibles en cómo los desarrolladores escriben y mantienen los archivos de configuración YAML. Conocer las causas habituales te ayuda a detectarlas en el origen.
Crecimiento del archivo de configuración con el tiempo
Los archivos de configuración longevos acumulan cambios de muchos colaboradores. Una clave definida hace meses cerca del principio del archivo la redefine un nuevo colaborador que no se dio cuenta de que ya existía. Es especialmente común en archivos `values.yaml` de Helm, ConfigMaps de Kubernetes y archivos de variables de Ansible, donde cientos de claves pueden repartirse en un archivo demasiado largo para revisarlo entero.
Fusionar fragmentos de configuración de distintos equipos
Cuando dos equipos independientes o microservicios contribuyen a una configuración YAML compartida, la misma clave de nivel superior puede estar definida por ambos. El archivo fusionado final contiene las dos definiciones y, silenciosamente, gana la que aparece en último lugar. Es una fuente habitual de errores de anulación específicos de entorno en los que el valor del equipo equivocado se aplica en producción.
Patrón de comentar y reemplazar
Un desarrollador comenta `timeout: 30` y añade `timeout: 60` justo debajo como reemplazo. Más tarde, alguien quita los caracteres de comentario de la línea antigua, quizá en un buscar y reemplazar global o con un formateador mal configurado, y ambos valores quedan activos. Gana el último, pero cuál es el último depende de dónde quedó cada línea en el archivo.
Errores de plantillas o generación de código
Las canalizaciones de CI/CD y las herramientas de infraestructura como código suelen generar YAML de forma programática. Un error en la lógica de la plantilla, como una rama condicional que no excluye correctamente una clave ya emitida por otra rama, puede producir YAML de aspecto válido con duplicados silenciosos. El archivo generado pasa el análisis de yaml-cpp y el valor equivocado se usa en producción sin registrar ningún error.
Aviso
Detectar y prevenir duplicados
Detectar claves duplicadas es sencillo con las herramientas adecuadas. El reto es atraparlas antes de que lleguen a un analizador de producción, no después de que ya se haya producido la pérdida silenciosa de datos. Este flujo de trabajo cubre la detección en todas las etapas, desde la escritura hasta el despliegue.
Paso 1: detección previa a la confirmación con el Detector de claves duplicadas en YAML
El Detector de claves duplicadas en YAML analiza todo tu documento YAML, incluidos los mapeos anidados a cualquier profundidad, y reporta cada clave duplicada con sus números de línea y tanto el valor sobrescrito como el superviviente. Pega tu archivo antes de confirmar para detectar problemas al instante. Sin subidas, sin registro y el archivo nunca sale de tu navegador.
Paso 2: linting en el editor con yamllint
Para equipos que trabajan a diario con archivos YAML, `yamllint` con la regla `key-duplicates` en `enable` detecta duplicados en cada guardado. Los usuarios de VS Code pueden instalar la extensión YAML (Red Hat), que integra yamllint automáticamente. Añadir yamllint a tus hooks previos a la confirmación y a tu canalización de CI hace que los duplicados nunca lleguen a una revisión de código donde podrían pasarse por alto.
Paso 3: análisis en modo estricto en tu suite de pruebas
Aunque tu código de producción use yaml-cpp, puedes añadir una validación en tiempo de prueba con un analizador estricto. Analiza cada archivo de configuración YAML con `yaml.v3` de Go o ruamel.yaml de Python en modo estricto como parte de tu suite de pruebas. Estos analizadores dan error con duplicados, lo que te proporciona un fallo de prueba contundente en lugar de un error silencioso en tiempo de ejecución. Después de ejecutar tus comprobaciones de duplicados, usa el Validador de anclas y alias de YAML para confirmar también que el uso de anclas y alias está limpio.
Detector de claves duplicadas en YAML
Encuentra al instante todas las claves duplicadas en cualquier documento YAML: se analiza cada nivel de anidamiento, se informan los números de línea y se muestran ambos valores en paralelo.
Prevención: buenas prácticas estructurales
- Ordena las claves alfabéticamente: el orden alfabético hace trivial detectar duplicados durante la revisión de código
- Usa anclas de YAML para valores compartidos: en lugar de duplicar un bloque, define un ancla una vez y referénciala con un alias
- Aplica yamllint en CI: una canalización que falla es una señal mucho más fuerte que un comentario en la revisión de código
- Revisa los diff grandes de configuración en conjunto: revisa la vista completa del archivo, no solo las líneas cambiadas, al revisar cambios de configuración
- Mantén los archivos cortos: divide los archivos de configuración grandes en subarchivos enfocados para reducir la superficie de duplicados
Claves de fusión, anclas y otras trampas
La clave de fusión de YAML (`<<`) y el sistema de anclas y alias son los mecanismos legítimos para reutilizar valores en un documento. Entender cómo interactúan con la detección de claves duplicadas evita falsos positivos en tus herramientas y te ayuda a usarlos con seguridad.
Cómo funcionan las claves de fusión
La clave de fusión `<<` indica a un analizador YAML que incorpore los pares clave-valor de un mapeo anclado al mapeo actual. No es una clave duplicada: `<<` es un indicador reservado en la especificación YAML 1.1 y una extensión ampliamente soportada en 1.2. Cuando una clave de fusión importa una clave que ya existe en el mapeo destino, la definición explícita del destino tiene prioridad sobre el valor fusionado. Es un comportamiento intencionado y predecible, a diferencia de las claves duplicadas accidentales.
Anclas y detección de duplicados
Las anclas de YAML (`&name`) y los alias (`*name`) no son duplicados. Un ancla define un nodo reutilizable y un alias lo referencia. Ambos pueden aparecer muchas veces en un documento sin crear una violación de claves duplicadas. El Validador de anclas y alias de YAML comprueba específicamente que cada alias se resuelve a un ancla declarada y que no hay referencias circulares, problemas distintos de las claves duplicadas.
Cuándo las claves de fusión producen duplicados aparentes
Una clave de fusión puede crear lo que parece un duplicado si el mapeo base anclado y el mapeo destino definen la misma clave. No es un error: la especificación define que las claves explícitas tienen prioridad sobre las claves fusionadas. Sin embargo, algunos linters de claves duplicadas lo reportan como error. Si ves falsos positivos en yamllint con configuraciones basadas en `<<`, confirma que estás usando bien las claves de fusión antes de silenciar la advertencia. Para archivos `values.yaml` de Helm complejos que usan mucho las anclas, comparar versiones con el Resaltador de diferencias para configuraciones JSON/YAML facilita detectar cambios a nivel de clave en las solicitudes de extracción.
Nota
Puntos clave
- yaml-cpp usa gana el último valor con las claves duplicadas: los valores anteriores se sobrescriben en silencio, sin error ni advertencia.
- La especificación YAML 1.2 dice explícitamente que las claves duplicadas no están permitidas y describe el comportamiento como indefinido.
- El comportamiento varía mucho entre analizadores: `yaml.v3` de Go da error con duplicados, mientras que PyYAML y js-yaml conservan el último valor en silencio como yaml-cpp.
- Las claves críticas para la seguridad como `admin` o `enabled` son los objetivos más peligrosos: un duplicado puede conceder o revocar acceso de forma invisible.
- Usa el Detector de claves duplicadas en YAML para analizar cualquier archivo YAML y encontrar duplicados en cada nivel de anidamiento antes del despliegue.
- Añade `yamllint` con `key-duplicates: enable` a tu canalización de CI para prevención automática en cada confirmación.
- Las claves de fusión de YAML (`<<`) y las anclas no son duplicados: son mecanismos de reutilización intencionados con reglas de prioridad definidas.