louthy/language-ext · error · ArgumentException

An element with the same key already exists in the set

Error message

An element with the same key already exists in the set

What it means

This ArgumentException is thrown by Set.Internal's Add<OrdK, K> when the key being inserted compares equal to an existing node's key. Sets cannot hold duplicates and, unlike the map variant, there is no TryAdd/TryUpdate option here, so a duplicate key is always rejected. The faulting input is the duplicate key argument to Add.

Solutions

  1. De-duplicate the source sequence before adding (Distinct with the same comparer)
  2. Use TryAdd or check Contains first
  3. Verify the Ord instance used matches the intended equality semantics

Example fix

// before
set = items.Fold(set, (s, x) => s.Add(x)); // throws on duplicates
// after
set = items.Distinct().Fold(set, (s, x) => s.Add(x));
Defensive patterns

Strategy: validation

Validate before calling

if (!set.Contains(key)) set = set.Add(key);

Try / catch

try { set = Set.add(key, set); }
catch (ArgumentException) { /* duplicate - ignore or log */ }

Prevention

When it happens

Trigger: Set.Add / set-cons operations where Ord.Compare(existing, key) == 0, e.g. re-adding an element or case-insensitive duplicates colliding under the comparer.

Common situations: Bulk-loading data with duplicate values, or wrong Ord type argument (e.g. OrdString.CaseInsensitive vs OrdString.Ordinal) causing unexpected collisions.

Related errors


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

Appendix: source

Thrown at LanguageExt.Core/Immutable Collections/Set/Internal/Set.Internal.cs:989

    [Pure]
    public static SetItem<K> Add<OrdK, K>(SetItem<K> node, K key) where OrdK : Ord<K>
    {
        if (node.IsEmpty)
        {
            return new SetItem<K>(1, 1, key, SetItem<K>.Empty, SetItem<K>.Empty);
        }
        var cmp = OrdK.Compare(key, node.Key);
        if (cmp < 0)
        {
            return Balance(Make(node.Key, Add<OrdK, K>(node.Left, key), node.Right));
        }
        else if (cmp > 0)
        {
            return Balance(Make(node.Key, node.Left, Add<OrdK, K>(node.Right, key)));
        }
        else
        {
            throw new ArgumentException("An element with the same key already exists in the set");
        }
    }

    [Pure]
    public static SetItem<K> TryAdd<OrdK, K>(SetItem<K> node, K key) where OrdK : Ord<K>
    {
        if (node.IsEmpty)
        {
            return new SetItem<K>(1, 1, key, SetItem<K>.Empty, SetItem<K>.Empty);
        }
        var cmp = OrdK.Compare(key, node.Key);
        if (cmp < 0)
        {
            return Balance(Make(node.Key, TryAdd<OrdK, K>(node.Left, key), node.Right));
        }
        else if (cmp > 0)
        {
            return Balance(Make(node.Key, node.Left, TryAdd<OrdK, K>(node.Right, key)));

View on GitHub (pinned to 2f0e362824)