louthy/language-ext · error · ArgumentException

Key not found in Map

Error message

Key not found in Map

What it means

MapInternal.SetItem(key, Func<V,V> Some) updates an existing value via the supplied function but throws ArgumentException('Key not found in Map') when MapModule.TryFind returns None — i.e. the key is absent. Unlike the AddOrUpdate-style 'SetItem that ignores missing keys' variant, this overload demands the key exist. Null keys are silently ignored (returns this) rather than throwing here.

Solutions

  1. Use the Find/map API or the TrySetItem/SetItem-or-add variant if you want upsert semantics (e.g. AddOrUpdate pattern).
  2. Check map.ContainsKey(key) (or Find) before applying the updater.
  3. Fix the key construction so it matches the key used at insert.
  4. Insert the key first (Add) when absence is expected, then update.

Example fix

// before
var map2 = map.SetItem(key, v => v + 1); // throws if key absent
// after
var map2 = map.Find(key)
    .Match(Some: v => map.SetItem(key, v + 1),
           None: () => map.Add(key, 1));
Defensive patterns

Strategy: validation

Validate before calling

var map2 = map.ContainsKey(key)
    ? map.SetItem(key, v => v + 1)
    : map.Add(key, 1);

Try / catch

try { var map2 = map.SetItem(key, updater); }
catch (ArgumentException ex) when (ex.Message == "Key not found in Map")
{
    // key absent — add or ignore
}

Prevention

When it happens

Trigger: Calling SetItem(key, updater) where key was never inserted or was already removed; key exists only in a different Map snapshot; case/type differences making the key mismatch (e.g. string casing under default Ord).

Common situations: Assuming SetItem acts as upsert (it does not in this overload); updating after a Remove in the same immutable pipeline; building keys by concatenation that differ from insert-time keys; culture-sensitive string keys.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

        return SetRoot(MapModule.SetItem<OrdK, K, V>(Root, key, value));
    }

    /// <summary>
    /// Retrieve a value from the map by key, map it to a new value,
    /// put it back.
    /// </summary>
    /// <param name="key">Key to set</param>
    /// <exception cref="ArgumentException">Throws ArgumentException if the item isn't found</exception>
    /// <exception cref="Exception">Throws Exception if Some returns null</exception>
    /// <returns>New map with the mapped value</returns>
    [Pure]
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public MapInternal<OrdK, K, V> SetItem(K key, Func<V, V> Some) =>
        isnull(key)
            ? this
            : match(MapModule.TryFind<OrdK, K, V>(Root, key),
                    Some: x => SetItem(key, Some(x)),
                    None: () => throw new ArgumentException("Key not found in Map"));

    /// <summary>
    /// Atomically updates an existing item, unless it doesn't exist, in which case 
    /// it is ignored
    /// </summary>
    /// <remarks>Null is not allowed for a Key or a Value</remarks>
    /// <param name="key">Key</param>
    /// <param name="value">Value</param>
    /// <exception cref="ArgumentNullException">Throws ArgumentNullException the value is null</exception>
    /// <returns>New Map with the item added</returns>
    [Pure]
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public MapInternal<OrdK, K, V> TrySetItem(K key, V value)
    {
        if (isnull(key)) return this;
        return SetRoot(MapModule.TrySetItem<OrdK, K, V>(Root, key, value));
    }

View on GitHub (pinned to 2f0e362824)