{"record":{"id":"970060cbaa347ff8","repo":"RicoSuter/NSwag","slug":"an-item-with-the-same-key-has-already-been-added","errorCode":null,"errorMessage":"An item with the same key has already been added.","messagePattern":"An item with the same key has already been added\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/NSwag.Core/Collections/ObservableDictionary.cs","lineNumber":85,"sourceCode":"        /// <summary>Gets the underlying dictonary. </summary>\n        protected Dictionary<TKey, TValue> Dictionary => _dictionary;\n\n        /// <summary>Adds multiple key-value pairs the the dictionary. </summary>\n        /// <param name=\"items\">The key-value pairs. </param>\n        public void AddRange(IDictionary<TKey, TValue> items)\n        {\n            if (items == null)\n            {\n                throw new ArgumentNullException(nameof(items));\n            }\n\n            if (items.Count > 0)\n            {\n                if (_dictionary.Count > 0)\n                {\n                    if (items.Keys.Any(k => _dictionary.ContainsKey(k)))\n                    {\n                        throw new ArgumentException(\"An item with the same key has already been added.\");\n                    }\n\n                    foreach (var pair in items)\n                    {\n                        _dictionary.Add(pair.Key, pair.Value);\n                    }\n                }\n                else\n                {\n                    _dictionary = new Dictionary<TKey, TValue>(items);\n                }\n\n                OnCollectionChanged(NotifyCollectionChangedAction.Add, items.ToArray());\n            }\n        }\n\n        /// <summary>Inserts a key-value pair into the dictionary. </summary>\n        /// <param name=\"key\">The key. </param>","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/RicoSuter/NSwag/blob/63daf8fcc3a25151b62eb4b326a1e8ea048a0d41/src/NSwag.Core/Collections/ObservableDictionary.cs#L67-L103","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove duplicate keys from the incoming dictionary before AddRange","Use the indexer or the non-add overload to overwrite existing keys intentionally","Check _dictionary.ContainsKey for each key first and skip/handle conflicts"],"exampleFix":"// before\ndict.AddRange(newItems); // throws if key exists\n// after\nforeach (var pair in newItems)\n{\n    dict[pair.Key] = pair.Value; // overwrite instead\n}","handlingStrategy":"validation","validationCode":"bool hasConflict = items.Keys.Any(k => dict.ContainsKey(k));\nif (!hasConflict) dict.AddRange(items);","typeGuard":null,"tryCatchPattern":"try { dict.AddRange(items); } catch (ArgumentException ex) { /* resolve duplicate keys: merge or overwrite */ }","preventionTips":["Deduplicate input dictionaries by key before merging","Prefer indexer assignment when overwrite semantics are acceptable"],"tags":["nswag","duplicate-key","dictionary"],"backgroundTag":"duplicate-key","analyzedSha":"63daf8fcc3a25151b62eb4b326a1e8ea048a0d41","analyzedAt":"2026-09-14T11:38:15.205Z","contentChangedAt":"2026-09-14T11:38:15.205Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}