{"record":{"id":"8edfe54ab880a972","repo":"louthy/language-ext","slug":"indexoutofrangeexception-seq","errorCode":null,"errorMessage":"IndexOutOfRangeException","messagePattern":"IndexOutOfRangeException","errorType":"exception","errorClass":"IndexOutOfRangeException","httpStatus":null,"severity":"error","filePath":"LanguageExt.Core/Immutable Collections/Seq/Seq.cs","lineNumber":99,"sourceCode":"            : Tail.IsEmpty \n                ? Head.Value\n                : (Head.Value, Tail);\n\n    public void Deconstruct(out A head, out Seq<A> tail)\n    {\n        head = Head.IfNone(() => throw Exceptions.SequenceEmpty);\n        tail = Tail;\n    }\n\n    [MethodImpl(MethodImplOptions.AggressiveInlining)]\n    public ReadOnlySpan<A> AsSpan() =>\n        Value.AsSpan();\n\n    /// <summary>\n    /// Head lens\n    /// </summary>\n    public static Lens<Seq<A>, A> head => Lens<Seq<A>, A>.New(\n        Get: la => la.IsEmpty ? throw new IndexOutOfRangeException() : la[0],\n        Set: a => la => la.IsEmpty ? throw new IndexOutOfRangeException() : a.Cons(la.Tail)\n    );\n\n    /// <summary>\n    /// Head or none lens\n    /// </summary>\n    public static Lens<Seq<A>, Option<A>> headOrNone => Lens<Seq<A>, Option<A>>.New(\n        Get: la => la.Head,\n        Set: a => la => la.IsEmpty || a.IsNone ? la : a.Value.Cons(la.Tail!)!\n    );\n\n    /// <summary>\n    /// Tail lens\n    /// </summary>\n    public static Lens<Seq<A>, Seq<A>> tail => Lens<Seq<A>, Seq<A>>.New(\n        Get: la => la.IsEmpty ? Empty : la.Tail,\n        Set: a => la => la.IsEmpty ? a : ((A)la.Head).Cons(a)\n    );","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/louthy/language-ext/blob/2f0e3628242889774d4141960a35671a0280051f/LanguageExt.Core/Immutable Collections/Seq/Seq.cs#L81-L117","documentation":"LanguageExt's Seq.head lens throws IndexOutOfRangeException when the target Seq is empty. Lenses are total-style accessors but the head lens cannot produce a value for an empty sequence, so it throws instead of returning Option. The exception comes from the Get (or Set) lambda of the lens when la.IsEmpty is true.","triggerScenarios":"Calling Seq<A>.head.Get() on an empty Seq, or head.Set() on an empty Seq. Any code path that applies the head lens without first checking IsEmpty.","commonSituations":"Taking the first element of a query/filter result that returned no items; processing a file or stream that produced zero lines; refactoring from List.First() to Seq.head without preserving the empty-collection check.","solutions":["Check la.IsEmpty (or la.Count == 0) before applying the head lens","Use the headOrNone lens instead, which returns Option<A> and never throws","Use Seq.head() / HeadOrNone() extension functions rather than the lens","Wrap the lens application in try-catch for IndexOutOfRangeException if the empty case is expected"],"exampleFix":"// before\nvar first = Seq.head.Get(mySeq);\n// after\nvar first = mySeq.IsEmpty ? Option<A>.None : Seq.headOrNone.Get(mySeq);","handlingStrategy":"validation","validationCode":"if (seq.IsEmpty) throw new InvalidOperationException(\"Cannot get head of empty Seq\");\nvar first = Seq.head.Get(seq);","typeGuard":"static bool HasHead<A>(Seq<A> s) => !s.IsEmpty;","tryCatchPattern":"try { first = Seq.head.Get(seq); }\ncatch (IndexOutOfRangeException) { first = default; /* empty seq */ }","preventionTips":["Prefer headOrNone lens over head for fallible access","Check IsEmpty before any lens that requires elements","Use HeadOrNone()/head() extension functions which return Option"],"tags":["csharp","languageext","seq","lens","empty-collection"],"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"}