louthy/language-ext · error · IndexOutOfRangeException

IndexOutOfRangeException

Error message

IndexOutOfRangeException

What it means

AsSpan(int start) returns a read-only span beginning at the given index of the Arr. It throws IndexOutOfRangeException when start is negative or >= the Arr's length. The XML doc on the method explicitly declares this exception for an out-of-range start index.

Solutions

  1. Check start is within [0, arr.Length) before calling AsSpan; use arr.AsSpan() for the whole span.
  2. Clamp the index: arr.AsSpan(Math.Clamp(start, 0, arr.Length - 1)) when a valid non-empty Arr is guaranteed.
  3. Handle empty Arrs by returning ReadOnlySpan<A>.Empty instead of slicing.

Example fix

// before
var span = arr.AsSpan(offset);
// after
var span = offset >= 0 && offset < arr.Count ? arr.AsSpan(offset) : ReadOnlySpan<int>.Empty;
Defensive patterns

Strategy: validation

Validate before calling

bool ok = start >= 0 && start < arr.Count;
if (!ok) return ReadOnlySpan<int>.Empty;
var span = arr.AsSpan(start);

Type guard

static bool CanSpanAt<T>(Arr<T> a, int start) => (uint)start < (uint)a.Count;

Try / catch

try { return arr.AsSpan(start); }
catch (IndexOutOfRangeException) { return ReadOnlySpan<int>.Empty; }

Prevention

When it happens

Trigger: Calling arr.AsSpan(start) where start < 0 or start >= arr.Length, most commonly start == arr.Length on an empty or exactly-exhausted Arr.

Common situations: Iterating windows in a loop without re-checking the shrinking length, hot-path parsing code that assumes a minimum span size, or slicing an Arr that unexpectedly came back empty from a filter/map chain.

Related errors


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

Appendix: source

Thrown at LanguageExt.Core/Immutable Collections/Arr/Arr.cs:126

    /// <returns>A read-only span of values</returns>
    /// <exception cref="IndexOutOfRangeException">Thrown If the start index is outside the range of the array</exception>
    [Pure]
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public ReadOnlySpan<A> AsSpan() =>
        new (Value, start, length);

    /// <summary>
    /// Create a readonly sub-span of this array.  This doesn't do any copying, so is very fast, but be aware that any
    /// items outside the splice are still active.   
    /// </summary>
    /// <param name="start">Offset from the beginning of the array</param>
    /// <returns>A read-only span of values</returns>
    /// <exception cref="IndexOutOfRangeException">Thrown If the start index is outside the range of the array</exception>
    [Pure]
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public ReadOnlySpan<A> AsSpan(int start)
    {
        if (start < 0 || start >= length) throw new IndexOutOfRangeException(nameof(start));
        var t = Math.Max(0, length - start);
        return new(Value, this.start + start, t);
    }

    /// <summary>
    /// Create a readonly sub-span of this array.  This doesn't do any copying, so is very fast, but be aware that any
    /// items outside the splice are still active.   
    /// </summary>
    /// <param name="start">Offset from the beginning of the array</param>
    /// <param name="count">The number of items to take. This will be clamped to the maximum number of items available</param>
    /// <returns>A read-only span of values</returns>
    /// <exception cref="IndexOutOfRangeException">Thrown If the start index is outside the range of the array</exception>
    [Pure]
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public ReadOnlySpan<A> AsSpan(int start, int count)
    {
        if (start < 0 || start >= length) throw new IndexOutOfRangeException(nameof(start));
        var t = Math.Max(0, Math.Min(count, length - start));

View on GitHub (pinned to 2f0e362824)