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
- Check IsSome before casting
- Use ma.Match(Some: v => v, None: () => default) or IfNone(default) for safe extraction
- Convert to Option's safe API surface (Bind/Map) instead of unwrapping
- 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
- Never force-cast Options; use IfNone/Match
- Check IsSome before explicit conversion
- Handle parse failures (ParseOption) before unwrapping
- Prefer Bind/Map chains over extraction
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
- Bug in MonadLaw or Monad.unsafeRecur. Contact language-ext…
- Ord attribute should have a struct type that derives from…
- Hashable attribute should have a struct type that derives…
- Don't use Equals - use either RecordType
- Don't use Equals - use either RecordType
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)