louthy/language-ext · error · IndexOutOfRangeException

IndexOutOfRangeException

Error message

IndexOutOfRangeException

What it means

SeqLazy's indexer evaluates At(index), which forces the underlying lazy enumerator up to the index; if the option comes back None (index beyond available elements) it throws IndexOutOfRangeException. Note At on a lazy seq consumes elements up to the index.

Solutions

  1. Check bounds first; for lazy seqs prefer Take + iteration over random access
  2. Use At()/TryAt-style Option access instead of the indexer when length is unknown
  3. Materialize with ToSeq()/ToArray() if you need reliable indexing and length

Example fix

// before
var x = lazySeq[10];
// after
var x = lazySeq.At(10).IfNone(default(A));
Defensive patterns

Strategy: type-guard

Validate before calling

bool inBounds = index >= 0 && index < lazySeq.Count; // forces evaluation

Type guard

Option<A> TryAt<A>(SeqLazy<A> seq, int i) => seq.At(i);

Try / catch

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

Prevention

When it happens

Trigger: Indexing a lazily-evaluated Seq with an index >= the number of elements the lazy source yields, or < 0.

Common situations: Indexing results of infinite/lazy generators by a fixed index assuming a minimum length; iterating with stale Count after the source changed; off-by-one with <= bounds.

Related errors


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

Appendix: source

Thrown at LanguageExt.Core/Immutable Collections/Seq/DSL/SeqLazy.cs:83

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    SeqLazy(A[] data, int start, int count, int noCons, Enum<A> seq, int seqStart)
    {
        this.data = data;
        this.start = start;
        this.count = count;
        this.seq = seq;
        this.seqStart = seqStart;
        consDisallowed = noCons;
    }

    public A this[int index]
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        get
        {
            var r = At(index);
            if (r.IsSome) return r.Value!;
            throw new IndexOutOfRangeException();
        }
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public Option<A> At(int index)
    {
        if (index < 0) return default;
        if (index < count) return data[^count];
        var lazyIndex = index                      - count + seqStart;
        var (succ, val) = StreamTo(lazyIndex);
        return succ
                   ? val
                   : default(Option<A>);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    (bool Success, A? Value) StreamTo(int index)
    {

View on GitHub (pinned to 2f0e362824)