louthy/language-ext · error · ArgumentException

An element with the same key already exists in the Map

Error message

An element with the same key already exists in the Map

What it means

Deep inside MapModule's insertion logic (the Add path reached from MapInternal), the tree walk finds a node whose key compares equal to the key being added and — instead of updating — throws ArgumentException('An element with the same key already exists in the Map'). It enforces that Add is strictly insert-new; duplicates must go through SetItem/update paths.

Solutions

  1. Use SetItem for add-or-update semantics instead of Add when duplicates are legitimate.
  2. Guard with Find/ContainsKey before Add and branch to SetItem on presence.
  3. Normalize keys identically everywhere (e.g. Ord.amountOrd / ToLowerInvariant) before insertion.
  4. Deduplicate the source data (e.g. GroupBy key, take last) before bulk-loading into the Map.

Example fix

// before
var map2 = map.Add(key, value); // throws if key exists
// after
var map2 = map.Find(key)
    .Match(Some: _ => map.SetItem(key, value),
           None: () => map.Add(key, value));
Defensive patterns

Strategy: validation

Validate before calling

var map2 = map.ContainsKey(key)
    ? map.SetItem(key, value)
    : map.Add(key, value);

Try / catch

try { var map2 = map.Add(key, value); }
catch (ArgumentException ex) when (ex.Message.Contains("same key already exists"))
{
    var map2 = map.SetItem(key, value); // fall back to update
}

Prevention

When it happens

Trigger: Calling map.Add(key, v) (or MapModule.Add) when key already exists; re-adding after a merge or bulk load that already inserted the key; ordinal-vs-culture comparisons making two string keys compare as equal here but distinct elsewhere.

Common situations: Seeding a Map from config/dictionary data that contains duplicate keys; idempotency retries inserting the same record twice; keys normalized differently at write vs insert time.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15). Data as JSON: /api/errors/a8bf58110faf8251. Report an issue: GitHub.

Appendix: source

Thrown at LanguageExt.Core/Immutable Collections/Map/Map.Internal.cs:1885

        else if (cmp > 0)
        {
            node.Right = Add<OrdK, K, V>(node.Right, key, value, option);
            return Balance(node);
        }
        else if(option == AddOpt.TryAdd)
        {
            // Already exists, but we don't care
            return node;
        }
        else if (option == AddOpt.TryUpdate)
        {
            // Already exists, and we want to update the content
            node.KeyValue = (key, value);
            return node;
        }
        else
        {
            throw new ArgumentException("An element with the same key already exists in the Map");
        }
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static MapItem<K, V> Balance<K, V>(MapItem<K, V> node)
    {
        node.Height = (byte)(1 + Math.Max(node.Left.Height, node.Right.Height));
        node.Count = 1 + node.Left.Count + node.Right.Count;

        return node.BalanceFactor >= 2
                   ? node.Right.BalanceFactor < 0
                         ? DblRotLeft(node)
                         : RotLeft(node)
                   : node.BalanceFactor <= -2
                       ? node.Left.BalanceFactor > 0
                             ? DblRotRight(node)
                             : RotRight(node)
                       : node;

View on GitHub (pinned to 2f0e362824)