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
- Read fault.Code and fault.Message to identify which BPMN element/error signaled the fault.
- Handle the BPMN error in the model (add an error boundary event / error handler) if it is expected behavior.
- 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
- Model error boundary events for expected BPMN errors.
- Validate gateway/task expressions before deployment.
- Monitor fault codes to distinguish model bugs from expected error events.
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
- AlterationFaultCodes.PlanNotFound
- FaultException raised by Fault activity
- No alterations found in the transient properties.
- No alteration log found in the transient properties.
- An < : > element declares no ' ', so there is nothing to…
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 aView on GitHub (pinned to fe9217bdfa)