elsa-workflows/elsa-core · error · ObjectDisposedException
IWorkflowCommitNotificationScope
Error message
IWorkflowCommitNotificationScope
What it means
The scope object implementing IWorkflowCommitNotificationScope guards against use after disposal. ThrowIfDisposed throws ObjectDisposedException(nameof(IWorkflowCommitNotificationScope)) when any member is accessed after the scope was disposed (e.g. after the workflow commit completed).
Solutions
- Ensure all notification enqueueing happens within the scope's lifetime (before Dispose / before the workflow completes).
- Do not capture the scope in background tasks; capture the data and enqueue synchronously during the commit.
- Check _disposed (IsDisposed) before using the scope if lifetime is uncertain.
- Restructure so the scope follows the using/RAII pattern tightly around the code that needs it.
Example fix
// before _scope = notificationScope; // stored in field, used after commit // after using var scope = await factory.BeginScopeAsync(ct); scope.Enqueue(notification, strategy); // scope disposed here; never used afterwards
Defensive patterns
Strategy: try-catch
Validate before calling
if (scope is IDisposable d && /* track disposed flag */ false) { /* check before use */ } Type guard
bool ScopeUsable(IWorkflowCommitNotificationScope scope) => scope is not { } disposedScope || !IsDisposed(disposedScope); // prefer storing your own _disposed flag Try / catch
try
{
scope.Enqueue(notification, strategy);
}
catch (ObjectDisposedException)
{
logger.LogWarning("Commit notification scope already disposed; notification dropped.");
} Prevention
- Scope all notification enqueues inside the scope's using lifetime
- Never capture the scope in fire-and-forget tasks
- Enqueue synchronously before workflow commit completes
When it happens
Trigger: Holding a reference to an IWorkflowCommitNotificationScope (obtained via BeginScope-like APIs) and calling methods on it after Dispose, such as enqueueing notifications from a background task that outlives the workflow execution.
Common situations: Fire-and-forget tasks capturing the scope and writing notifications after the workflow finished; using a scope stored in a long-lived field; accidentally disposing the scope in a using block while still enqueuing afterwards.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- A workflow definition handle must be provided.
- Drain already completed in this generation; subsequent…
- Drain already in progress; second invocation rejected
- Duplicate ingress source registration for name
- Either ActivityTypeName or StimulusHash must be specified.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/498da954d1608626.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Workflows.Runtime/Services/WorkflowCommitNotificationBuffer.cs:85
if (exceptions is { Count: > 0 })
throw new AggregateException("One or more workflow commit notifications failed.", exceptions);
}
public void Dispose()
{
if (_disposed)
return;
_disposed = true;
if (ReferenceEquals(owner._currentScope.Value, this))
owner._currentScope.Value = parent;
}
private void ThrowIfDisposed()
{
if (_disposed)
throw new ObjectDisposedException(nameof(IWorkflowCommitNotificationScope));
}
}
private record Entry(INotification Notification, IEventPublishingStrategy? Strategy);
}
View on GitHub (pinned to fe9217bdfa)