RicoSuter/NSwag · error · ArgumentException

An item with the same key has already been added.

Error message

An item with the same key has already been added.

What it means

ObservableDictionary.AddRange pre-checks whether any key in the incoming items dictionary already exists in the target dictionary and throws ArgumentException to prevent silently overwriting entries. Unlike the fallback Add path, this bulk method validates all keys upfront so the operation is atomic — either all items are added or none are.

Solutions

  1. Remove duplicate keys from the incoming dictionary before AddRange
  2. Use the indexer or the non-add overload to overwrite existing keys intentionally
  3. Check _dictionary.ContainsKey for each key first and skip/handle conflicts

Example fix

// before
dict.AddRange(newItems); // throws if key exists
// after
foreach (var pair in newItems)
{
    dict[pair.Key] = pair.Value; // overwrite instead
}
Defensive patterns

Strategy: validation

Validate before calling

bool hasConflict = items.Keys.Any(k => dict.ContainsKey(k));
if (!hasConflict) dict.AddRange(items);

Try / catch

try { dict.AddRange(items); } catch (ArgumentException ex) { /* resolve duplicate keys: merge or overwrite */ }

Prevention

When it happens

Trigger: Calling AddRange with a dictionary containing at least one key already present in the ObservableDictionary, e.g. merging two sets of schemas/parameters that share a key.

Common situations: Merging generated OpenAPI components (schemas, security schemes) from two sources into one document, or calling AddRange twice with overlapping data after re-running a generator.

Related errors


AI-assisted analysis of RicoSuter/NSwag@63daf8fcc3 (2026-09-14). Data as JSON: /api/errors/970060cbaa347ff8. Report an issue: GitHub.

Appendix: source

Thrown at src/NSwag.Core/Collections/ObservableDictionary.cs:85

        /// <summary>Gets the underlying dictonary. </summary>
        protected Dictionary<TKey, TValue> Dictionary => _dictionary;

        /// <summary>Adds multiple key-value pairs the the dictionary. </summary>
        /// <param name="items">The key-value pairs. </param>
        public void AddRange(IDictionary<TKey, TValue> items)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            if (items.Count > 0)
            {
                if (_dictionary.Count > 0)
                {
                    if (items.Keys.Any(k => _dictionary.ContainsKey(k)))
                    {
                        throw new ArgumentException("An item with the same key has already been added.");
                    }

                    foreach (var pair in items)
                    {
                        _dictionary.Add(pair.Key, pair.Value);
                    }
                }
                else
                {
                    _dictionary = new Dictionary<TKey, TValue>(items);
                }

                OnCollectionChanged(NotifyCollectionChangedAction.Add, items.ToArray());
            }
        }

        /// <summary>Inserts a key-value pair into the dictionary. </summary>
        /// <param name="key">The key. </param>

View on GitHub (pinned to 63daf8fcc3)