elsa-workflows/elsa-core · error · BpmnScopeFaultException

{fault.Code}

{fault.Code}

Error message

{fault.Message}

What it means

BpmnScopeHost.ApplyAsync evaluates the interpreter's continuation; a BpmnContinuation.Fault result is surfaced by throwing BpmnScopeFaultException carrying the interpreter-provided fault Code and Message. This is the host's way of propagating a genuine BPMN execution fault (e.g. an error event or expression failure) as a domain exception.

Solutions

  1. Read fault.Code and fault.Message to identify which BPMN element/error signaled the fault.
  2. Handle the BPMN error in the model (add an error boundary event / error handler) if it is expected behavior.
  3. If unexpected, inspect diagnostics/logs for the failing element and fix its expression or configuration.
Defensive patterns

Strategy: try-catch

Try / catch

try { await host.EvaluateAsync(...); }
catch (BpmnScopeFaultException ex) { log.LogWarning("BPMN fault {Code}: {Message}", ex.Code, ex.Message); /* route to error handler / boundary event */ }

Prevention

When it happens

Trigger: A workflow evaluation in the BPMN scope host returns a Fault continuation — e.g. a BPMN error event fired, an expression evaluation fault, or an interpreter-detected model violation — during EvaluateAsync/ApplyAsync.

Common situations: End-signaling an error boundary event; a service task failing with a mapped BPMN error; gateway condition expressions throwing.

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/675dc781b19c41af. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.Bpmn/Hosting/BpmnScopeHost.cs:217

            memory.SaveState();

            await ApplyAsync(memory, evaluation);
        });

    private async ValueTask ApplyAsync(BpmnScopeMemory memory, BpmnEvaluation evaluation)
    {
        await new BpmnCommandApplier(_context, _process, memory).ApplyAsync(evaluation.Commands);

        switch (evaluation.Continuation)
        {
            case BpmnContinuation.Complete complete:
                // The scope completes because the interpreter said so, never because it ran out of children.
                await _context.CompleteActivityAsync(new Outcomes(complete.Outcome));
                break;
            case BpmnContinuation.Defer:
                break;
            case BpmnContinuation.Fault fault:
                throw new BpmnScopeFaultException(fault.Code, fault.Message);
            default:
                throw new NotSupportedException($"The BPMN continuation '{evaluation.Continuation.GetType().Name}' is not supported by this host.");
        }
    }

    /// <summary>
    /// Projects every diagnostic the interpreter has appended since the last evaluation onto this scope's own
    /// execution log, keyed by element id. Under Option A only bound work has an activity id, so a gateway, an
    /// intermediate event or a sequence flow has nothing else in the journal to say where a token went; this is
    /// write-only and never read back by the interpreter or this host.
    /// </summary>
    /// <remarks>
    /// Runs on <see cref="_context"/> — this scope's own context — and never a child's: the diagnostic describes
    /// this scope's decision about a child, and the child may already be torn down by the time this runs. Called
    /// with the evaluation's own <see cref="BpmnEvaluation.State"/>, before <c>Prune()</c> caps
    /// <see cref="BpmnExecutionState.Diagnostics"/> at 200 entries, because projecting from what was actually
    /// persisted would lose whatever pruning already dropped. The last diagnostic id it has projected is kept in
    /// <see cref="BpmnScopeMemory.DiagnosticsCursorPropertyKey"/> so a resumed scope does not re-emit one a

View on GitHub (pinned to fe9217bdfa)