AvaloniaUI/Avalonia · error · InvalidOperationException

Optional has no value.

Error message

Optional has no value.

What it means

Optional<T> is an either-or container (like Nullable<T> but it accepts reference types). Accessing .Value when HasValue is false is invalid because there is no stored value. The struct throws InvalidOperationException to mirror Nullable<T>.Value semantics.

Source

Thrown at src/Avalonia.Base/Data/Optional.cs:47

        /// <param name="value">The value.</param>
        public Optional(T value)
        {
            _value = value;
            HasValue = true;
        }

        /// <summary>
        /// Gets a value indicating whether a value is present.
        /// </summary>
        public bool HasValue { get; }

        /// <summary>
        /// Gets the value.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// <see cref="HasValue"/> is false.
        /// </exception>
        public T Value => HasValue ? _value : throw new InvalidOperationException("Optional has no value.");

        /// <inheritdoc/>
        public override bool Equals(object? obj) => obj is Optional<T> o && this == o;

        /// <inheritdoc/>
        public bool Equals(Optional<T> other) => this == other;

        /// <inheritdoc/>
        public override int GetHashCode() => HasValue ? _value?.GetHashCode() ?? 0 : 0;

        /// <summary>
        /// Casts the value (if any) to an <see cref="object"/>.
        /// </summary>
        /// <returns>The cast optional value.</returns>
        public Optional<object?> ToObject() => HasValue ? new Optional<object?>(_value) : default;

        /// <inheritdoc/>
        public override string ToString() => HasValue ? _value?.ToString() ?? "(null)" : "(empty)";

View on GitHub (pinned to 11c5427268)

Solutions

  1. Check `optional.HasValue` before accessing `.Value`.
  2. Use pattern matching: `if (opt.HasValue) { ... opt.Value ... }`.
  3. Provide a fallback with `opt.HasValue ? opt.Value : defaultValue`.

Example fix

// before:
var x = optional.Value; // throws if empty

// after:
if (optional.HasValue)
    Use(optional.Value);
else
    Use(fallback);
// or:
var x = optional.HasValue ? optional.Value : default(T);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!optional.HasValue) return fallback;
var v = optional.Value;

Type guard

static bool IsPresent<T>(Optional<T> o) => o.HasValue;

Try / catch

try { var v = optional.Value; }
catch (InvalidOperationException) { /* no value; use default */ }

Prevention

When it happens

Trigger: Reading `optional.Value` on a default/empty Optional<T> (e.g. `default(Optional<T>)` or `Optional<T>.Empty`), or after an operation that returned an empty optional.

Common situations: Binding value lookups, converter inputs, or property metadata that return Optional<T>.Empty, then code blindly reads .Value. Default struct initialization leaves HasValue=false.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/87b464df607412e8. Report an issue: GitHub.