{"record":{"id":"9a83c6547907d989","repo":"louthy/language-ext","slug":"index-outside-the-bounds-of-the-list","errorCode":null,"errorMessage":"Index outside the bounds of the list","messagePattern":"Index outside the bounds of the list","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"LanguageExt.Core/Immutable Collections/List/Internal/Lst.Internal.cs","lineNumber":761,"sourceCode":"        {\n            return Balance(Make(node.Key, Insert(node.Left, key, index), node.Right));\n        }\n        else\n        {\n            return Balance(Make(node.Key, node.Left, Insert(node.Right, key, index - node.Left.Count - 1)));\n        }\n    }\n\n    public static ListItem<A> Add<A>(ListItem<A> node, A key) =>\n        node.IsEmpty\n            ? new ListItem<A>(1, 1, ListItem<A>.Empty, key, ListItem<A>.Empty)\n            : Balance(Make(node.Key, node.Left, Add(node.Right, key)));\n\n    public static ListItem<A> SetItem<A>(ListItem<A> node, A key, int index)\n    {\n        if (node.IsEmpty)\n        {\n            throw new ArgumentException(\"Index outside the bounds of the list\");\n        }\n\n        if (index == node.Left.Count)\n        {\n            return new ListItem<A>(node.Height, node.Count, node.Left, key, node.Right);\n        }\n        else if (index < node.Left.Count)\n        {\n            return new ListItem<A>(node.Height, node.Count, SetItem(node.Left, key, index), node.Key, node.Right);\n        }\n        else\n        {\n            return new ListItem<A>(node.Height, node.Count, node.Left, node.Key, SetItem(node.Right, key, index - node.Left.Count - 1));\n        }\n    }\n\n    public static T GetItem<T>(ListItem<T> node, int index)\n    {","sourceCodeStart":743,"sourceCodeEnd":779,"githubUrl":"https://github.com/louthy/language-ext/blob/2f0e3628242889774d4141960a35671a0280051f/LanguageExt.Core/Immutable Collections/List/Internal/Lst.Internal.cs#L743-L779","documentation":"ListModule.SetItem (the AVL tree worker behind LstInternal.SetItem) throws ArgumentException('Index outside the bounds of the list') when it descends to an empty node while seeking the target index. This is a defensive internal invariant check: the public SetItem normally rejects bad indices first, so reaching it means the index equaled or exceeded the subtree count during recursion.","triggerScenarios":"SetItem with index >= Root.Count that bypasses the public guard (e.g. a stale Root where the index was valid for an earlier snapshot); direct ListModule.SetItem calls with an out-of-range index; index == node.Left.Count is the only 'replace' position, anything larger falls into the empty-node path.","commonSituations":"Race-like inconsistencies from mixing list snapshots in async code; custom code invoking ListModule internals; passing indices derived from a different collection.","solutions":["Always go through Lst/LstInternal.SetItem and validate index against the same instance you mutate.","Ensure index is in 0..Count-1 for the exact snapshot being updated.","Avoid calling ListModule.SetItem directly; treat it as internal API.","Audit async workflows so an index computed from one snapshot is never applied to another."],"exampleFix":"// before\nvar node = ListModule.SetItem(root, value, i); // i may exceed root.Count\n// after\nif (i < 0 || i >= root.Count) throw new ArgumentOutOfRangeException(nameof(i));\nvar node = ListModule.SetItem(root, value, i);","handlingStrategy":"validation","validationCode":"if (i < 0 || i >= root.Count)\n    throw new ArgumentOutOfRangeException(nameof(i));\nvar node = ListModule.SetItem(root, value, i);","typeGuard":null,"tryCatchPattern":"try { var node = ListModule.SetItem(root, value, i); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Index outside\"))\n{\n    // index did not exist in this tree snapshot\n}","preventionTips":["Avoid ListModule internals; use Lst/LstInternal public APIs that pre-validate.","Ensure the index is validated against the same Root snapshot passed down.","In async code, never carry an index from one immutable snapshot into another.","Add assertions that 0 <= index < node.Count before tree recursion in custom extensions."],"tags":["csharp","languageext","list","avl-tree","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"2f0e3628242889774d4141960a35671a0280051f","analyzedAt":"2026-09-15T03:31:55.716Z","contentChangedAt":"2026-09-15T03:31:55.716Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}