louthy/language-ext · error · InvalidCastException

Option is not in a Some state

Error message

Option is not in a Some state

What it means

The explicit cast operator (A)Option<A> throws InvalidCastException ('Option is not in a Some state') when the Option is None. Explicit conversion is an unsafe extraction: it only works when the Option holds a value.

Solutions

  1. Check IsSome before casting
  2. Use ma.Match(Some: v => v, None: () => default) or IfNone(default) for safe extraction
  3. Convert to Option's safe API surface (Bind/Map) instead of unwrapping
  4. Catch InvalidCastException around the explicit cast if None is possible

Example fix

// before
var v = (int)maybeInt; // InvalidCastException when None

// after
var v = maybeInt.IfNone(0); // or check: if (maybeInt.IsSome) { ... }
Defensive patterns

Strategy: type-guard

Validate before calling

if (option.IsSome) { var v = (A)option; } else { /* None path */ }

Type guard

bool TryGet<A>(Option<A> ma, out A value) { value = ma.IfNone(default!); return ma.IsSome; }

Try / catch

try { var v = (A)option; }
catch (InvalidCastException ex) when (ex.Message == "Option is not in a Some state") { var v = default(A); }

Prevention

When it happens

Trigger: Writing var x = (A)someOption; (explicit cast) on an Option<A> whose IsSome is false — i.e. a None value reaching the operator at Option.cs:177.

Common situations: Porting nullable-style code to Option and using casts; deserialization producing None then cast; parsed values (ParseOption) that fail silently and are later force-cast.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at LanguageExt.Core/Monads/Alternative Monads/Option/Option.cs:177

    }
    
    /// <summary>
    /// Must exist here to make `operator true` work
    /// </summary>
    public static Option<A> operator |(Option<A> lhs, Option<A> rhs) =>
        lhs.Choose(rhs).As();

    /// <summary>
    /// Explicit conversion operator from `Option〈A〉` to `A`
    /// </summary>
    /// <param name="a">None value</param>
    [Pure]
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static explicit operator A(Option<A> ma)
    {
        var opExplicit = ma.IsSome
                             ? ma.Value
                             : throw new InvalidCastException("Option is not in a Some state");
        
        return opExplicit!;
    }

    /// <summary>
    /// Implicit conversion operator from A to Option〈A〉
    /// </summary>
    /// <param name="a">Unit value</param>
    [Pure]
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static implicit operator Option<A>(A? a) =>
        Optional(a);

    /// <summary>
    /// Implicit conversion operator from None to Option〈A〉
    /// </summary>
    /// <param name="a">None value</param>
    [Pure]

View on GitHub (pinned to 2f0e362824)