louthy/language-ext · error · InvalidOperationException

Nil iterator has no head

Error message

Nil iterator has no head

What it means

The Nil (empty) case of the Iterator discriminated union has no head element, so accessing its Head property throws InvalidOperationException. This is the iterator-DSL equivalent of calling List.head on an empty list.

Solutions

  1. Check `iter.IsEmpty` (or match on Nil/Cons style) before reading Head.
  2. Use the library's Fold/Map/Filter combinators instead of manual Head/Tail recursion.
  3. If a value must exist, guard with a Try/Optional wrapper such as `iter.IsEmpty ? Prelude.None : Some(iter.Head)`.

Example fix

// before
var head = iter.Head;
// after
var head = iter.IsEmpty ? Prelude.None : Prelude.Some(iter.Head);
Defensive patterns

Strategy: validation

Validate before calling

if (iter.IsEmpty) throw new InvalidOperationException("Cannot take Head of an empty iterator");
var head = iter.Head;

Type guard

static Option<A> TryHead<A>(Iterator<A> it) => it.IsEmpty ? Prelude.None : Prelude.Some(it.Head);

Try / catch

try { head = iter.Head; }
catch (InvalidOperationException) { head = Option<A>.None; }

Prevention

When it happens

Trigger: Accessing `.Head` on an Iterator<A> that is the Nil case — typically obtained by walking Tail off a single-element iterator, or constructing Iterator.Nil<A>() and reading Head directly.

Common situations: Hand-rolled recursive iteration that recurses past the last element (checking Head before IsEmpty); assuming an iterator is non-empty; off-by-one Tail traversal in pattern-matching-style code.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at LanguageExt.Core/Immutable Collections/Iterator/DSL/Iterator.Nil.cs:35

    K<Iterator, A>
{
    /// <summary>
    /// Nil iterator case
    ///
    /// The end of the sequence.
    /// </summary>
    public sealed class Nil : Iterator<A>
    {
        public static readonly Iterator<A> Default = new Nil();

        public override string ToString() => 
            "Nil";

        /// <summary>
        /// Head element
        /// </summary>
        public override A Head =>
            throw new InvalidOperationException("Nil iterator has no head");

        /// <summary>
        /// Tail of the sequence
        /// </summary>
        public override Iterator<A> Tail =>
            this;

        /// <summary>
        /// Return true if there are no elements in the sequence.
        /// </summary>
        public override bool IsEmpty =>
            true;

        /// <summary>
        /// Clone the iterator so that we can consume it without having the head item referenced.
        /// This will stop any GC pressure.
        /// </summary>
        public override Iterator<A> Clone() =>

View on GitHub (pinned to 2f0e362824)