louthy/language-ext · error · ArgumentNullException

ArgumentNullException

Error message

ArgumentNullException

What it means

Guard's internal constructor taking Func<E> onFalse throws ArgumentNullException when the onFalse delegate is null. A Guard must always know how to produce its error value E for the false branch, so a null factory is rejected at construction.

Solutions

  1. Provide a non-null error factory when constructing Guard.
  2. Use the E-based constructor with a default error value instead of a null Func.
  3. Coalesce: onFalse ?? (() => defaultError) before constructing.

Example fix

// before
var g = new Guard<E, A>(flag, maybeFactory); // maybeFactory may be null
// after
var g = new Guard<E, A>(flag, maybeFactory ?? (() => defaultError));
Defensive patterns

Strategy: validation

Validate before calling

onFalse ?? throw new ArgumentNullException(nameof(onFalse));

Type guard

static bool ValidFactory<E>(Func<E> f) => f is not null;

Try / catch

try { var g = new Guard<E,A>(flag, f); } catch (ArgumentNullException) { /* null factory */ }

Prevention

When it happens

Trigger: Calling new Guard<E,A>(flag, (Func<E>)null) or passing a null lambda through the internal API (e.g. from generated/language-ext combinators that propagate a null onFalse).

Common situations: Refactoring where a lazily-evaluated error factory variable became null, or binding results of optional error-providing functions directly into Guard.

Related errors


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

Appendix: source

Thrown at LanguageExt.Core/Guard.cs:18

using System;
using static LanguageExt.Prelude;

namespace LanguageExt;

/// <summary>
/// Used by various error-producing monads to have a contextual `where`
/// </summary>
/// <remarks>
/// See `Prelude.guard(...)`
/// </remarks>
public readonly struct Guard<E, A>
{
    public readonly bool Flag;
    readonly Func<E> onFalse;

    internal Guard(bool flag, Func<E> onFalse) =>
        (Flag, this.onFalse) = (flag, onFalse ?? throw new ArgumentNullException(nameof(onFalse)));

    internal Guard(bool flag, E onFalse)
    {
        if (isnull(onFalse)) throw new ArgumentNullException(nameof(onFalse));
        (Flag, this.onFalse) = (flag, () => onFalse);
    }

    public Guard<E, B> Cast<B>() =>
        new (Flag, OnFalse);
        
    public Func<E> OnFalse =>
        onFalse ?? throw new InvalidOperationException(
            "Guard isn't initialised. It was probably created via new Guard() or default(Guard), and so it has no OnFalse handler");

    public Guard<E, C> SelectMany<C>(Func<E, Guard<E, Unit>> bind, Func<Unit, Unit, C> project) =>
        Flag ? bind(default!).Cast<C>() : Cast<C>();

    public Guard<E, B> Select<B>(Func<B, B> _) =>

View on GitHub (pinned to 2f0e362824)