{"record":{"id":"b5253445cd62dda3","repo":"stride3d/stride","slug":"index-out-of-range","errorCode":null,"errorMessage":"index out of range","messagePattern":"index out of range","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core/Collections/SortedList.cs","lineNumber":411,"sourceCode":"    {\n        var table = this.table;\n        var cnt = Count;\n        if (index >= 0 && index < cnt)\n        {\n            if (index != cnt - 1)\n            {\n                Array.Copy(table, index + 1, table, index, cnt - 1 - index);\n            }\n            else\n            {\n                table[index] = default(KeyValuePair<TKey, TValue>);\n            }\n            --inUse;\n            ++modificationCount;\n        }\n        else\n        {\n            throw new ArgumentOutOfRangeException(\"index out of range\");\n        }\n    }\n\n    public int IndexOfKey(TKey key)\n    {\n        ArgumentNullException.ThrowIfNull(key);\n\n        var indx = 0;\n        try\n        {\n            indx = Find(key);\n        }\n        catch (Exception)\n        {\n            throw new InvalidOperationException();\n        }\n\n        return (indx | (indx >> 31));","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core/Collections/SortedList.cs#L393-L429","documentation":"RemoveAt(int index) validates that the supplied index falls within [0, Count). If not (including on an empty list), it throws ArgumentOutOfRangeException with the message \"index out of range\". SortedList exposes positional removal because it keeps keys sorted in its internal table.","triggerScenarios":"RemoveAt(i) where i < 0 or i >= sortedList.Count; RemoveAt on an empty list (RemoveAt(0)); using a stale index captured before another element was removed.","commonSituations":"Looping RemoveAt(i) upward while removing matching items (shifts indices); Remove(key) internally calling RemoveAt(IndexOfKey(key)) when the key is absent and callers bypass checks; UI/list synchronization using out-of-date indexes.","solutions":["Check 0 <= index && index < sortedList.Count before calling RemoveAt.","When removing inside a loop, iterate downward (for i = Count-1; i >= 0; i--) so shifts do not invalidate indices.","Prefer Remove(key) if you have the key; it looks up the position for you and no-ops on missing keys.","Use IndexOfKey(key) and check the returned index before RemoveAt."],"exampleFix":"// before\nfor (int i = 0; i < list.Count; i++)\n    if (predicate(list.Values[i])) list.RemoveAt(i);\n// after\nfor (int i = list.Count - 1; i >= 0; i--)\n    if (predicate(list.Values[i])) list.RemoveAt(i);","handlingStrategy":"validation","validationCode":"if (index < 0 || index >= sortedList.Count)\n    return false; // or throw your own descriptive error\nsortedList.RemoveAt(index);","typeGuard":"static bool IsValidIndex(System.Collections.Generic.SortedList<TKey,TValue> list, int i) =>\n    (uint)i < (uint)list.Count;","tryCatchPattern":"try { sortedList.RemoveAt(index); }\ncatch (ArgumentOutOfRangeException ex) when (ex.Message == \"index out of range\")\n{ /* index was stale; refetch Count or skip */ }","preventionTips":["Iterate backwards when removing multiple items by index.","Never cache indices across mutations of the list.","Check Count for empty lists before RemoveAt(0).","Prefer Remove(key) or IndexOfKey + guard over raw positional removal."],"tags":["collections","index-out-of-range","sortedlist"],"backgroundTag":"index-out-of-range","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"}