{"record":{"id":"f1d975fafbdb426f","repo":"OrchardCMS/OrchardCore","slug":"can-t-resolve-a-scope-on-tenant-settings-name-as-it-is","errorCode":null,"errorMessage":"Can't resolve a scope on tenant '{Settings.Name}' as it is disabled or disposed","messagePattern":"Can't resolve a scope on tenant '(.+?)' as it is disabled or disposed","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.Abstractions/Shell/Builders/ShellContext.cs","lineNumber":249,"sourceCode":"\n            // Remove any previous instance that represents the same tenant in case it has been released or reloaded.\n            _dependents.RemoveAll(wref => !wref.TryGetTarget(out var shell) || shell.Settings.Name == shellContext.Settings.Name);\n\n            _dependents.Add(new WeakReference<ShellContext>(shellContext));\n        }\n        finally\n        {\n            _semaphore.Release();\n        }\n    }\n\n    internal void AddRef()\n    {\n        // The service provider is null if we try to create\n        // a scope on a disabled shell or already disposed.\n        if (ServiceProvider is null)\n        {\n            throw new InvalidOperationException(\n               $\"Can't resolve a scope on tenant '{Settings.Name}' as it is disabled or disposed\");\n        }\n\n        int current;\n        do\n        {\n            current = _refCount;\n            if (current < 0)\n            {\n                throw new InvalidOperationException(\n                   $\"Can't resolve a scope on tenant '{Settings.Name}' as the shell context is already terminated\");\n            }\n            // Try to increment _refCount only if it is not <= -1\n        }\n        while (Interlocked.CompareExchange(ref _refCount, current + 1, current) != current);\n\n        if (Interlocked.CompareExchange(ref _terminated, 0, 0) != 0)\n        {","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.Abstractions/Shell/Builders/ShellContext.cs#L231-L267","documentation":"ShellContext.AddRef increments the shell's reference count before creating a ShellScope. ServiceProvider is null when the shell is disabled or has been disposed, making scope creation impossible, so AddRef throws InvalidOperationException naming the tenant.","triggerScenarios":"Creating a ShellScope (ShellScope.CreateScope/UsingAsync) for a tenant whose ShellContext was disabled (e.g. tenant stopped in admin, feature-level shutdown) or already disposed (released during shutdown/rebuild).","commonSituations":"Background jobs or singletons holding an old shell reference after a tenant restart, requests racing tenant reload/dispose, or code resolving scopes for a disabled tenant in a multi-tenant setup.","solutions":["Check shellContext.ServiceProvider is not null (and IsActive) before creating a scope.","Re-resolve the current ShellContext via IShellContextFactory/IShellSettingsManager instead of caching stale references.","Disable or guard the background work for tenants that are disabled (check ShellSettings.IsRunning / State).","Retry the operation after obtaining a fresh shell context, since the old one is permanently gone."],"exampleFix":"// before\nusing var scope = await _shellContext.CreateScopeAsync();\n// after\nif (_shellContext.ServiceProvider is null || !_shellContext.Settings.IsRunning())\n{\n    _shellContext = await _shellContextFactory.GetShellContextAsync(_shellContext.Settings);\n}\nusing var scope = await _shellContext.CreateScopeAsync();","handlingStrategy":"validation","validationCode":"if (shellContext.ServiceProvider is null || !shellContext.Settings.IsRunning()) { /* re-resolve or skip */ }","typeGuard":"bool CanCreateScope(ShellContext s) => s.ServiceProvider is not null && s.Settings.IsRunning();","tryCatchPattern":"try { using var scope = shellContext.CreateScope(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"disabled or disposed\")) { /* re-resolve fresh shell context */ }","preventionTips":["Never cache ShellContext instances across long-running operations","Check tenant state before background work","Re-resolve shell contexts through IShellHost instead of holding references"],"tags":["multi-tenancy","shell-lifecycle","disposed"],"backgroundTag":"invalid-state-transition","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}