PowerShell-Yayaml icon indicating copy to clipboard operation
PowerShell-Yayaml copied to clipboard

Duplicate key error when using multiple merge anchors (<<) with the same key in YAML

Open Dmitry-True opened this issue 3 months ago • 1 comments

Description:

When parsing a YAML document that contains multiple merge anchors (<<: *anchor) in the same mapping — even if they reference different anchors — the ConvertFrom-Yaml command throws an error:

ConvertFrom-Yaml : Duplicate key << This occurs even though the YAML is syntactically valid and the merge keys are intended to apply multiple anchor expansions in sequence (as allowed by the YAML spec).

Example to Reproduce:

$actual = ConvertFrom-Yaml @'
dict:
  test: &anchor2
    key5: value
    key6: test value
  entry1: &anchor
    key1: value 1
    key2: value 2
  entry2:
    <<: *anchor
    key2: other value
    key3: final value
  entry3:
    key2: other value
    key3: final value
    <<: *anchor
    <<: *anchor2
'@ -Schema Yaml11

Expected Behavior:

The command should successfully parse the YAML, merging the content from both *anchor and *anchor2 into entry3. The resulting structure should include all keys from both anchors, with later keys overriding earlier ones if there are conflicts (per YAML merge key semantics).

Notes:

The YAML specification allows multiple << keys in a single mapping (though it's rare), and some YAML parsers handle this by merging each anchor in order. Even if the behavior should be modified (e.g., to warn or merge sequentially), the current implementation should not fail outright unless explicitly designed to reject such constructs. At minimum, the error message should be more descriptive if multiple merge keys are intentionally disallowed.

Dmitry-True avatar Aug 25 '25 09:08 Dmitry-True

Looks like this might unfortunately be a limitation in YamlDotNet, specifically how the YamlStream API works and how a YamlMappingNode works internally.

As this module uses YamlStream to parse the YAML data we are at the mercy of what YamlDotNet allows and in this case it finds << the second time and throws the duplicate key exception. This is because internally YamlMappingNode uses an OrderedDictionary to capture the mapping key values and this throws the duplicate key exception if the key already exists in the dictionary

https://github.com/aaubry/YamlDotNet/blob/b8ac2a98ffcc12434eff6c6abb75b38ad1b1ab04/YamlDotNet/RepresentationModel/YamlMappingNode.cs#L79-L82

The actual merging of the values in done in our custom 1.1 schema which checks for the << key and merges it at

https://github.com/jborean93/PowerShell-Yayaml/blob/174cbcaed66fa7753dcfa744c08b5b8f0a654355/src/Yayaml/Yaml11Schema.cs#L135-L150

Unfortunately as the internal structure of YamlDotNet does not support this we cannot really do anything about it here. The only thing that could theoretically be done is to move away from the YamlStream based API and use the more low level parsing event API. This would be a massive change internally and if I'm being honest I don't really have the time right now to even look at how that would actually work sorry.

jborean93 avatar Aug 31 '25 20:08 jborean93