@@ -588,11 +588,20 @@ fn validate_object(
588588 }
589589 } ;
590590
591- // Extract keys
591+ // Extract keys, rejecting duplicates. The source-tracked hash view
592+ // preserves every entry (the collapsed `Yaml::Hash` would not), so a
593+ // repeated key is detectable here. Report it on the second occurrence,
594+ // pointing at that key's span.
592595 let mut keys = HashSet :: new ( ) ;
593596 for entry in entries {
594- if let Yaml :: String ( ref key) = entry. key . yaml {
595- keys. insert ( key. clone ( ) ) ;
597+ if let Yaml :: String ( ref key) = entry. key . yaml
598+ && !keys. insert ( key. clone ( ) )
599+ {
600+ context. add_error (
601+ ValidationErrorKind :: DuplicateKey { key : key. clone ( ) } ,
602+ & entry. key ,
603+ ) ;
604+ return Err ( context. errors [ 0 ] . clone ( ) ) ;
596605 }
597606 }
598607
@@ -1800,6 +1809,40 @@ mod tests {
18001809 assert ! ( validate( & yaml, & schema, & registry, & source_ctx) . is_err( ) ) ;
18011810 }
18021811
1812+ #[ test]
1813+ fn test_validate_object_duplicate_keys ( ) {
1814+ let registry = SchemaRegistry :: new ( ) ;
1815+ let source_ctx = SourceContext :: new ( ) ;
1816+ let schema = Schema :: Object ( ObjectSchema {
1817+ annotations : SchemaAnnotations :: default ( ) ,
1818+ properties : HashMap :: new ( ) ,
1819+ pattern_properties : HashMap :: new ( ) ,
1820+ additional_properties : None ,
1821+ required : vec ! [ ] ,
1822+ min_properties : None ,
1823+ max_properties : None ,
1824+ closed : false ,
1825+ property_names : None ,
1826+ naming_convention : None ,
1827+ base_schema : None ,
1828+ } ) ;
1829+
1830+ // A mapping with a repeated key must be rejected, not silently deduped.
1831+ let yaml = yaml_object ( vec ! [
1832+ ( "examples" , Yaml :: String ( "a" . to_string( ) ) ) ,
1833+ ( "examples" , Yaml :: String ( "c" . to_string( ) ) ) ,
1834+ ] ) ;
1835+ let result = validate ( & yaml, & schema, & registry, & source_ctx) ;
1836+ let err = result. expect_err ( "duplicate key should fail validation" ) ;
1837+ assert_eq ! (
1838+ err. kind,
1839+ ValidationErrorKind :: DuplicateKey {
1840+ key: "examples" . to_string( ) ,
1841+ }
1842+ ) ;
1843+ assert_eq ! ( err. error_code( ) , "Q-1-20" ) ;
1844+ }
1845+
18031846 // ==================== AnyOf Tests ====================
18041847
18051848 #[ test]
0 commit comments