elsa-workflows/elsa-core · error · InvalidOperationException

Cannot access Value on a failed result. Check IsSuccess…

Error message

Cannot access Value on a failed result. Check IsSuccess first or use ValueOrDefault.

What it means

Result<T> models success/failure. The Value getter only exists for successful results; accessing it on a failed result throws this InvalidOperationException, with the original exception attached as innerException.

Solutions

  1. Check result.IsSuccess (or IsFailure) before accessing Value.
  2. Use result.ValueOrDefault when a default is acceptable for failures.
  3. Switch to a Match/switch expression handling both outcomes.
  4. Inspect result.Exception via the inner exception to diagnose the underlying failure.

Example fix

// before
var value = result.Value;
// after
if (!result.IsSuccess) return HandleFailure(result.Exception);
var value = result.Value;
Defensive patterns

Strategy: type-guard

Validate before calling

if (result.IsFailure)
    return HandleFailure(result.Exception);

Type guard

bool TryGetValue<T>(Result<T> result, out T? value) { value = result.IsSuccess ? result.Value : default; return result.IsSuccess; }

Try / catch

try { value = result.Value; }
catch (InvalidOperationException ex) when (ex.Message.Contains("failed result")) { value = fallback; }

Prevention

When it happens

Trigger: Reading result.Value without checking result.IsSuccess on a failed Result<T>, e.g. after an operation that returns a failure instead of throwing.

Common situations: Ignoring the IsSuccess flag in calling code; assuming an operation always succeeds; refactors that changed a throwing API into a Result-returning API without updating callers.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/2a1bf9e90a5db002. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.Common/Models/Result.cs:21

/// <summary>
/// A strongly typed monad that runs either the <see cref="OnSuccess"/> or <see cref="OnFailure"/> lambda, depending on whether or not the operation succeeded.
/// </summary>
public class Result<T>(bool success, T? value, Exception? exception)
{
    /// <summary>
    /// True if the conversion succeeded, false otherwise.
    /// </summary>
    public bool IsSuccess { get; } = success;

    /// <summary>
    /// The result value. Throws an exception if accessed when the result is a failure.
    /// </summary>
    public T Value
    {
        get
        {
            if (!IsSuccess)
                throw new InvalidOperationException("Cannot access Value on a failed result. Check IsSuccess first or use ValueOrDefault.", Exception);
            return value!;
        }
    }

    /// <summary>
    /// The result value, or null/default if the result is a failure. Useful when null is a valid success value.
    /// </summary>
    public T? ValueOrDefault => value;

    /// <summary>
    /// Any exception that may have occurred during the operation.
    /// </summary>
    public Exception? Exception { get; } = exception;

    /// <summary>
    /// Runs the provided delegate if the result is successful.
    /// </summary>
    public Result<T> OnSuccess(Action<T> successHandler)

View on GitHub (pinned to fe9217bdfa)