OrchardCMS/OrchardCore · error · InvalidOperationException

Can't resolve a scope on tenant

Error message

Can't resolve a scope on tenant '{Settings.Name}' as the shell context is already terminated

What it means

AddRef uses an interlocked compare-exchange loop on _refCount. A negative _refCount marks a terminated shell context (Release terminated it), so any further AddRef attempts throw InvalidOperationException because scopes can no longer be created on a terminated shell.

Solutions

  1. Do not cache ShellContext across operations; obtain it from the shell host each time so a rebuilt shell is used.
  2. Guard scope creation with a terminated/shell-running check before calling AddRef.
  3. Wrap scope creation in try/catch InvalidOperationException and re-resolve a fresh context once.
  4. Ensure long-running work completes or cancels before triggering tenant rebuild/termination.

Example fix

// before
var scope = _cachedShell.AddRef(); // may throw if terminated
// after
var shell = await _shellHost.GetScopeAsync(shellSettings);
using var scope = shell.CreateScope();
Defensive patterns

Strategy: try-catch

Try / catch

try { using var scope = shellContext.CreateScope(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("already terminated")) { shellContext = await _shellHost.GetShellContextAsync(settings); /* retry once */ }

Prevention

When it happens

Trigger: Calling AddRef (via ShellScope creation) after the ShellContext was terminated by Release, e.g. a concurrent request or background task grabbing a scope while the shell is being unloaded/rebuilt.

Common situations: Race between tenant reload and in-flight code, cached ShellContext references outliving termination, singletons capturing the shell during application shutdown.

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/63bb89f615e6d64f. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Abstractions/Shell/Builders/ShellContext.cs:259

    }

    internal void AddRef()
    {
        // The service provider is null if we try to create
        // a scope on a disabled shell or already disposed.
        if (ServiceProvider is null)
        {
            throw new InvalidOperationException(
               $"Can't resolve a scope on tenant '{Settings.Name}' as it is disabled or disposed");
        }

        int current;
        do
        {
            current = _refCount;
            if (current < 0)
            {
                throw new InvalidOperationException(
                   $"Can't resolve a scope on tenant '{Settings.Name}' as the shell context is already terminated");
            }
            // Try to increment _refCount only if it is not <= -1
        }
        while (Interlocked.CompareExchange(ref _refCount, current + 1, current) != current);

        if (Interlocked.CompareExchange(ref _terminated, 0, 0) != 0)
        {
            // If terminated, decrement back and throw
            Interlocked.Decrement(ref _refCount);

            throw new InvalidOperationException(
               $"Can't resolve a scope on tenant '{Settings.Name}' as the shell context is already terminated");
        }
    }

    internal bool Release()
    {

View on GitHub (pinned to 4306c0717f)