{"record":{"id":"2db2aec8602d0a65","repo":"stride3d/stride","slug":"an-item-with-the-same-key-has-already-been-added-2db2ae","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":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core/Collections/KeyedSortedList.cs","lineNumber":71,"sourceCode":"        items.RemoveAt(index);\n    }\n\n    /// <summary>\n    /// Sorts again this list (in case keys were mutated).\n    /// </summary>\n    public void Sort()\n    {\n        Array.Sort(items.Items, 0, items.Count, new Comparer(this));\n    }\n\n    /// <inheritdoc/>\n    public void Add(T item)\n    {\n        var key = GetKeyForItem(item);\n\n        var index = BinarySearch(key);\n        if (index >= 0)\n            throw new InvalidOperationException(\"An item with the same key has already been added.\");\n\n        InsertItem(~index, item);\n    }\n\n    public bool ContainsKey(TKey key)\n    {\n        return BinarySearch(key) >= 0;\n    }\n\n    public bool Remove(TKey key)\n    {\n        var index = BinarySearch(key);\n        if (index < 0)\n            return false;\n\n        RemoveItem(index);\n\n        return true;","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core/Collections/KeyedSortedList.cs#L53-L89","documentation":"KeyedSortedList derives a key from each item via GetKeyForItem and uses BinarySearch to keep items sorted. If BinarySearch finds the exact key (index >= 0), the key already exists and Add throws InvalidOperationException; it never inserts duplicates. Callers must remove the old item or use the indexer to replace it.","triggerScenarios":"Adding an item whose GetKeyForItem value equals the key of an item already in the list, e.g. list.Add(newItem) where an item with the same key was added earlier in the same session.","commonSituations":"Re-adding an updated entity (same key, new values) without removing the old one; loading the same entity twice from persistence; a key function (GetKeyForItem override) that returns identical keys for distinct items by mistake.","solutions":["Check ContainsKey(GetKeyForItem(item)) before Add, or remove the old item first","Replace via the indexer: list[index] = item after locating the existing entry","Review GetKeyForItem to ensure it returns a truly unique key per item","Catch InvalidOperationException around Add if duplicates are expected and handle them (e.g. skip or update)"],"exampleFix":"// before\nsortedList.Add(updatedEntity); // throws: same key exists\n// after\nint i = sortedList.IndexOf(updatedEntity);\nif (i >= 0) sortedList[i] = updatedEntity; else sortedList.Add(updatedEntity);","handlingStrategy":"validation","validationCode":"if (!list.ContainsKey(key)) list.Add(item);","typeGuard":null,"tryCatchPattern":"try { list.Add(item); } catch (InvalidOperationException) { /* update or skip duplicate */ }","preventionTips":["Check ContainsKey before Add","Ensure GetKeyForItem yields unique keys","Remove old entries before re-adding updated entities"],"tags":["csharp","collections","duplicate-key"],"backgroundTag":"file-already-exists","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}