louthy/language-ext · error · ArgumentException
Key already exists in map
Error message
Key already exists in map: {change.Key} What it means
During a TrieMap update traversal, when the key is found and the update type is Add (not SetItem/TryAdd), the library throws because Add is defined as insert-only: adding an existing key is an error. TryAdd silently keeps the existing entry instead. This enforces the semantic difference between Add and SetItem on the immutable map.
Solutions
- Use AddOrUpdate(key, value) or SetItem when overwriting is intended
- Use TryAdd when you want to keep the first value and ignore duplicates
- Deduplicate or group the source sequence before adding
- Check ContainsKey before Add if the branch logic requires it
Example fix
// before map = map.Add(key, value); // after map = map.AddOrUpdate(key, value);
Defensive patterns
Strategy: validation
Validate before calling
if (map.ContainsKey(key)) map = map.SetItem(key, value); else map = map.Add(key, value);
Try / catch
try { map = map.Add(key, value); }
catch (ArgumentException) { map = map.SetItem(key, value); } Prevention
- Use AddOrUpdate for upsert-style writes
- Use TryAdd when duplicates should be ignored
- Deduplicate bulk inputs before Add
When it happens
Trigger: Calling map.Add(key, value) (or union/duplicate-preserving bulk adds that route UpdateType.Add) on a TrieMap that already contains an equal key under its EqK comparer.
Common situations: Building a map from user-supplied key/value pairs containing duplicates; merging two maps with overlapping keys using Add semantics; case differences that a case-sensitive comparer treats as duplicates of different intent.
Related errors
- ArgumentOutOfRangeException
- An element with the same key already exists in the Map
- An element with the same key already exists in the Map
- An element with the same key already exists in the set
- Key doesn't exist in map
AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15).
Data as JSON: /api/errors/632856288e5ce671.
Report an issue: GitHub.
Appendix: source
Thrown at LanguageExt.Core/Immutable Collections/TrieMap/TrieMap.cs:2307
public (int CountDelta, Node Node, V? Old, bool Changed) Update((UpdateType Type, bool Mutate) env, (K Key, V Value) change, uint hash, Sec section)
{
// var hashIndex = Bit.Get(hash, section);
// var mask = Mask(hashIndex);
var mask = (uint)(1 << (int)((hash & (uint)(Sec.Mask << section.Offset)) >> section.Offset));
//if (Bit.Get(EntryMap, mask))
if((EntryMap & mask) == mask)
{
//var entryIndex = Index(EntryMap, mask);
var entryIndex = BitCount((int)EntryMap & ((int)mask - 1));
var currentEntry = Items[entryIndex];
if (EqK.Equals(currentEntry.Key, change.Key))
{
if (env.Type == UpdateType.Add)
{
// Key already exists - so it's an error to add again
throw new ArgumentException($"Key already exists in map: {change.Key}");
}
else if (env.Type == UpdateType.TryAdd)
{
// Already added, so we don't continue to try
return (0, this, default, false);
}
var (newItems, old) = SetItem(Items, entryIndex, change, env.Mutate);
return (0, new Entries(EntryMap, NodeMap, newItems, Nodes), old.Value, true);
}
else
{
if (env.Type == UpdateType.SetItem)
{
// Key must already exist to set it
throw new ArgumentException($"Key already exists in map: {change.Key}");
}
else if (env.Type == UpdateType.TrySetItem)View on GitHub (pinned to 2f0e362824)