{"record":{"id":"518cf9164bc544b8","repo":"louthy/language-ext","slug":"indexoutofrangeexception-seqconcat","errorCode":null,"errorMessage":"IndexOutOfRangeException","messagePattern":"IndexOutOfRangeException","errorType":"exception","errorClass":"IndexOutOfRangeException","httpStatus":null,"severity":"error","filePath":"LanguageExt.Core/Immutable Collections/Seq/DSL/SeqConcat.cs","lineNumber":27,"sourceCode":"namespace LanguageExt;\n\ninternal class SeqConcat<A>(Seq<ISeqInternal<A>> ms) : ISeqInternal<A>\n{\n    internal readonly Seq<ISeqInternal<A>> ms = ms;\n    \n    int selfHash;\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> AsSpan() =>\n        Strict().AsSpan();\n\n    public A this[int index]\n    {\n        get\n        {\n            var r = At(index);\n            if (r.IsSome) return r.Value!;\n            throw new IndexOutOfRangeException();\n        }\n    }\n\n    public Option<A> At(int index)\n    {\n        if (index < 0) return default;\n        var ms1 = ms;\n        while (!ms1.IsEmpty)\n        {\n            var head = ms1.Head.ValueUnsafe() ?? throw new InvalidOperationException();\n            var r    = head.At(index);\n            if (r.IsSome) return r;\n            index -= head.Count;\n            ms1 = ms1.Tail;\n        }\n        return default;\n    }\n","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/louthy/language-ext/blob/2f0e3628242889774d4141960a35671a0280051f/LanguageExt.Core/Immutable Collections/Seq/DSL/SeqConcat.cs#L9-L45","documentation":"SeqConcat's indexer calls At(index) and throws IndexOutOfRangeException when no underlying segment yields a Some for that index, i.e. the index is negative or past the end of the concatenated sequence.","triggerScenarios":"Indexing a Seq (backed by SeqConcat) with seq[i] where i >= seq.Count or i < 0.","commonSituations":"Off-by-one loops using <= Count; assuming a seq is non-empty; caching a Count from an earlier version of the immutable seq after taking/skipping.","solutions":["Check 0 <= index && index < seq.Count before indexing","Use seq[index] only inside bounds-checked loops","Use At-style Option access (TryAt) or pattern matching when bounds are uncertain"],"exampleFix":"// before\nvar x = seq[i];\n// after\nvar x = i >= 0 && i < seq.Count ? seq[i] : Option<A>.None;","handlingStrategy":"type-guard","validationCode":"bool inBounds = index >= 0 && index < seq.Count;","typeGuard":"Option<A> TryAt<A>(Seq<A> seq, int i) => i >= 0 && i < seq.Count ? seq[i] : Option<A>.None;","tryCatchPattern":"try { x = seq[index]; }\ncatch (IndexOutOfRangeException)\n{ x = fallback; }","preventionTips":["Never use <= in index loops over seq.Count","Use At()/HeadOrNone Option accessors when length is uncertain","Recheck Count after Skip/Take — the seq is immutable but may be a slice"],"tags":["csharp","languageext","seq","index-out-of-range"],"backgroundTag":"index-out-of-range","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"}