louthy/language-ext · error · IndexOutOfRangeException

IndexOutOfRangeException

Error message

IndexOutOfRangeException

What it means

This IndexOutOfRangeException is a range guard in the SeqStrict<A> indexer: it throws when the index is negative or >= count of the materialized array slice. The faulting input is the index argument; it fires on out-of-range access rather than wrapping, so callers must validate the index against Count first.

Solutions

  1. Validate 0 <= index && index < seq.Count before indexing
  2. Use slice-relative indices when indexing the result of Skip/Take
  3. Use At/HeadOrNone Option-based access when length is uncertain
  4. Convert to array and use standard bounds-checked loops for heavy random access

Example fix

// before
for (var i = 0; i <= seq.Count; i++) Use(seq[i]);
// after
for (var i = 0; i < seq.Count; i++) Use(seq[i]);
Defensive patterns

Strategy: type-guard

Validate before calling

bool inBounds = index >= 0 && index < seq.Count;

Type guard

Option<A> TryAt<A>(SeqStrict<A> seq, int i) => i >= 0 && i < seq.Count ? seq[i] : Option<A>.None;

Try / catch

try { x = seq[index]; }
catch (IndexOutOfRangeException)
{ x = fallback; }

Prevention

When it happens

Trigger: seq[i] with i < 0 or i >= seq.Count on a strict (array-backed) seq; slicing with start offsets then indexing with absolute rather than slice-relative indices.

Common situations: Off-by-one loops (i <= Count); using indices computed against the original collection after Skip/Take produced a slice; iterating a filtered seq with original indices.

Related errors


AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15). Data as JSON: /api/errors/f0ea1c0d826a2809. Report an issue: GitHub.

Appendix: source

Thrown at LanguageExt.Core/Immutable Collections/Seq/DSL/SeqStrict.cs:94

    /// Add constructor (called in the Add function only)
    /// </summary>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public SeqStrict(A[] data, int start, int count)
    {
        this.data = data;
        this.start = start;
        this.count = count;
        consDisallowed = NoCons;
    }

    /// <summary>
    /// Indexer
    /// </summary>
    public A this[int index]
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        get => index < 0 || index >= count
                   ? throw new IndexOutOfRangeException()
                   : data[start + index];
    }

    /// <summary>
    /// Indexer
    /// </summary>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public Option<A> At(int index) =>
        index < 0 || index >= count
            ? default(Option<A>)
            : data[start + index];

    /// <summary>
    /// Add an item to the end of the sequence
    /// </summary>
    /// <remarks>
    /// Forces evaluation of the entire lazy sequence so the item 
    /// can be appended

View on GitHub (pinned to 2f0e362824)