OrchardCMS/OrchardCore · error · InvalidOperationException
Cannot perform this operation because the shell scope for…
Error message
Cannot perform this operation because the shell scope for tenant '{ShellContext.Settings.Name}' is already terminating. What it means
ShellScope throws this InvalidOperationException when an operation (container registration, signal, or deferred task) is attempted on a shell scope that is already shutting down. It guards against mutating or relying on a scope whose disposal/termination has begun. This prevents work being enqueued into a scope that will never complete.
Solutions
- Check ShellScope.IsTerminating (or catch the exception) before deferring signals/tasks
- Move deferred task/signal scheduling earlier in the request pipeline
- Ensure background services use their own scope via IScopeService rather than a terminating request scope
- Retry the operation in a fresh scope after termination completes
Example fix
// before
await _shellScope.AddDeferredTaskAsync(myTask);
// after
if (!_shellScope.IsTerminating)
{
await _shellScope.AddDeferredTaskAsync(myTask);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (shellScope.IsTerminating) { return; } Type guard
bool canUseScope = shellScope is { IsTerminating: false }; Try / catch
try { await scope.AddDeferredTaskAsync(task); } catch (InvalidOperationException ex) when (ex.Message.Contains("already terminating")) { /* schedule after shutdown or drop */ } Prevention
- Check scope state before deferring work
- Avoid scheduling deferred tasks in disposal/shutdown paths
- Use dedicated background scopes for long-running work
When it happens
Trigger: Calling AddDeferredSignalAsync, AddDeferredTaskAsync, or using the scope's exception handler / container operations after the scope has entered the IsTerminating state (e.g., during request teardown or shell release).
Common situations: Background work scheduling during host shutdown; a signal or deferred task fired from a handler while the tenant is being recycled; race between middleware disposal and application code touching the scope.
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
- The 'Default' feature is not registered.
- Unable to reload the tenant
- Unexpected shell state for
- The tenant ' ' can't be removed as it is neither…
- Unknown token type
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/4501a0444cc5554d.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Abstractions/Shell/Scope/ShellScope.cs:594
Terminate();
}
private static void Terminate()
{
var holder = s_current.Value;
if (holder is not null)
{
// Clear the current scope that may be trapped in some execution contexts.
holder.Scope = null;
}
}
private void ThrowIfTerminating()
{
if (_state.HasFlag(ShellScopeStates.IsTerminating))
{
throw new InvalidOperationException(
$"Cannot perform this operation because the shell scope for tenant '{ShellContext.Settings.Name}' is already terminating.");
}
}
private sealed class ShellScopeHolder
{
public ShellScope Scope;
}
[Flags]
private enum ShellScopeStates : byte
{
ServiceScopeOnly = 1,
IsTerminating = 2,
IsDisposed = 4,
}
}
View on GitHub (pinned to 4306c0717f)