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

  1. Check ShellScope.IsTerminating (or catch the exception) before deferring signals/tasks
  2. Move deferred task/signal scheduling earlier in the request pipeline
  3. Ensure background services use their own scope via IScopeService rather than a terminating request scope
  4. 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

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


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)