{"record":{"id":"ff2795cb74c239ab","repo":"dotnet/aspnetcore","slug":"render-mode-already-set","errorCode":null,"errorMessage":"Render mode already set.","messagePattern":"Render mode already set\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/PersistentState/ComponentStatePersistenceManager.cs","lineNumber":167,"sourceCode":"            await store.PersistStateAsync(_currentState);\n            return true;\n        }\n    }\n\n    /// <summary>\n    /// Initializes the render mode for state persisted by the platform.\n    /// </summary>\n    /// <param name=\"renderMode\">The render mode to use for state persisted by the platform.</param>\n    /// <exception cref=\"InvalidOperationException\">when the render mode is already set.</exception>\n    public void SetPlatformRenderMode(IComponentRenderMode renderMode)\n    {\n        if (_servicesRegistry == null)\n        {\n            return;\n        }\n        else if (_servicesRegistry?.RenderMode != null)\n        {\n            throw new InvalidOperationException(\"Render mode already set.\");\n        }\n\n        _servicesRegistry!.RenderMode = renderMode;\n    }\n\n    private void InferRenderModes(Renderer renderer)\n    {\n        // We are iterating backwards to allow the callbacks to remove themselves from the list.\n        // Otherwise, we would have to make a copy of the list to avoid running into situations\n        // where we don't run all the callbacks because the count of the list changed while we\n        // were iterating over it.\n        // It is not allowed to register a callback while we are persisting the state, so we don't\n        // need to worry about new callbacks being added to the list.\n        for (var i = _registeredCallbacks.Count - 1; i >= 0; i--)\n        {\n            var registration = _registeredCallbacks[i];\n            if (registration.RenderMode != null)\n            {","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/PersistentState/ComponentStatePersistenceManager.cs#L149-L185","documentation":"ComponentStatePersistenceManager.SetPlatformRenderMode sets the render mode used for platform-persisted service state through PersistentServicesRegistry. The registry's RenderMode can be assigned exactly once; calling SetPlatformRenderMode again after a non-null render mode is already stored throws. This prevents conflicting platform render-mode declarations when multiple render hosts (e.g., Server and WebAssembly) attempt to claim the same registry.","triggerScenarios":"Invoking SetPlatformRenderMode twice with different IComponentRenderMode values on the same manager. A hosting layer that registers the platform render mode during prerender and a second layer registers it again during interactive startup. Two endpoints with different configured render modes sharing the same services registration.","commonSituations":"Misconfigured Blazor Web App where both a prerendering endpoint and an interactive circuit attempt to set the platform render mode. Custom hosts that call SetPlatformRenderMode in startup and again per-request. Mixing InteractiveServer and InteractiveWebAssembly platform configuration on the same app instance.","solutions":["Call SetPlatformRenderMode at most once per manager; delegate platform render-mode selection to a single owning layer.","If the mode is already set, skip the call; guard with a check of whether the registry already has a RenderMode if you have internal access.","Reconcile conflicting render-mode configuration so only one platform render mode applies per services registry."],"exampleFix":"// before: setting platform render mode twice\nmanager.SetPlatformRenderMode(RenderMode.InteractiveServer);\nmanager.SetPlatformRenderMode(RenderMode.InteractiveWebAssembly); // throws\n\n// after: set once; ensure only the platform host assigns it\nmanager.SetPlatformRenderMode(RenderMode.InteractiveServer);\n// do not call again; configure other endpoints to reuse the same manager","handlingStrategy":"validation","validationCode":"// Only one platform host should set the render mode.\nif (platformRenderMode == null) return;\ntry\n{\n    manager.SetPlatformRenderMode(platformRenderMode);\n}\ncatch (InvalidOperationException) { /* already set; ensure consistency */ }","typeGuard":null,"tryCatchPattern":"try { manager.SetPlatformRenderMode(renderMode); }\ncatch (InvalidOperationException ex) when (ex.Message == \"Render mode already set.\")\n{\n    // Log and verify the already-set mode matches expectation; otherwise reconcile config.\n}","preventionTips":["Assign the platform render mode from a single owning host layer.","Do not call SetPlatformRenderMode per-request; do it once at startup.","Ensure Blazor Web App render-mode configuration is consistent across endpoints."],"tags":["blazor","render-mode","persistent-state","configuration"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}