stride3d/stride · error · ArgumentException

An element with the same key has already been added.

Error message

An element with the same key has already been added.

What it means

IndexingDictionary.Add checks whether the slot for the given int key already holds an item via SafeGet and throws ArgumentException when it does. The dictionary intentionally requires Remove/insert semantics rather than silent overwrite. The indexer (this[key]) must be used to replace an existing value.

Solutions

  1. Use the indexer dict[key] = value to assign an existing key instead of Add
  2. Check ContainsKey(key) (or null-check via SafeGet) before calling Add
  3. Remove the existing entry with Remove(key) before re-adding
  4. Deduplicate the input data by key before populating the dictionary

Example fix

// before
dictionary.Add(id, item); // throws if id already present
// after
dictionary[id] = item; // inserts or overwrites
Defensive patterns

Strategy: validation

Validate before calling

if (!dict.ContainsKey(key)) dict.Add(key, value);

Try / catch

try { dict.Add(key, value); } catch (ArgumentException) { dict[key] = value; } // or skip

Prevention

When it happens

Trigger: Calling Add(key, value) on an IndexingDictionary<int,T> where that key already has a non-null entry; re-adding a key that was previously set through the indexer without removing it first.

Common situations: Populating the dictionary from a data source that contains duplicate keys (e.g. duplicate asset IDs); retrying initialization code after a partial failure so the same key is added twice; confusing Add with the indexer which overwrites.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/29ce0c0bb8d3f3cd. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core/Collections/IndexingDictionary.cs:117

                ++arrayIndex;
            }
            ++index;
        }
    }

    public bool Remove(KeyValuePair<int, T> item)
    {
        return SafeGet(item.Key) == item.Value && Remove(item.Key);
    }

    public bool ContainsKey(int index)
    {
        return SafeGet(index) != null;
    }

    public void Add(int key, T value)
    {
        if (SafeGet(key) != null) throw new ArgumentException("An element with the same key has already been added.");
        SafeSet(key, value);
    }

    public bool Remove(int index)
    {
        if (index < 0 || index >= items.Count)
            return false;

        if (items[index] == null)
            return false;

        items[index] = null;
        --Count;
        index = items.Count - 1;
        while (index >= 0 && items[index] == null)
        {
            items.RemoveAt(index);
            --index;

View on GitHub (pinned to 96fad776d2)