dotnet/aspnetcore · error · InvalidOperationException

Render mode already set.

Error message

Render mode already set.

What it means

Thrown by ComponentStatePersistenceManager.SetPlatformRenderMode when _servicesRegistry.RenderMode is already non-null. The platform render mode is a one-time configuration applied to the persistent-services registry and cannot be changed after it is set.

Source

Thrown at src/Components/Components/src/PersistentState/ComponentStatePersistenceManager.cs:167

            await store.PersistStateAsync(_currentState);
            return true;
        }
    }

    /// <summary>
    /// Initializes the render mode for state persisted by the platform.
    /// </summary>
    /// <param name="renderMode">The render mode to use for state persisted by the platform.</param>
    /// <exception cref="InvalidOperationException">when the render mode is already set.</exception>
    public void SetPlatformRenderMode(IComponentRenderMode renderMode)
    {
        if (_servicesRegistry == null)
        {
            return;
        }
        else if (_servicesRegistry?.RenderMode != null)
        {
            throw new InvalidOperationException("Render mode already set.");
        }

        _servicesRegistry!.RenderMode = renderMode;
    }

    private void InferRenderModes(Renderer renderer)
    {
        // We are iterating backwards to allow the callbacks to remove themselves from the list.
        // Otherwise, we would have to make a copy of the list to avoid running into situations
        // where we don't run all the callbacks because the count of the list changed while we
        // were iterating over it.
        // It is not allowed to register a callback while we are persisting the state, so we don't
        // need to worry about new callbacks being added to the list.
        for (var i = _registeredCallbacks.Count - 1; i >= 0; i--)
        {
            var registration = _registeredCallbacks[i];
            if (registration.RenderMode != null)
            {

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Call SetPlatformRenderMode exactly once during startup/configuration.
  2. Guard the call so it only runs on first configuration.
  3. If you must change render mode, use a new ComponentStatePersistenceManager instance.
  4. When using the default framework integration, let it set the platform render mode instead of calling this manually.

Example fix

// before
app.Use(async (ctx, next) => {
    manager.SetPlatformRenderMode(InteractiveServer); // runs each request -> throws
    await next();
});

// after: set once at startup
manager.SetPlatformRenderMode(InteractiveServer);
Defensive patterns

Strategy: validation

Validate before calling

private bool _renderModeSet;

void SetPlatformRenderModeOnce(ComponentStatePersistenceManager manager, IComponentRenderMode mode)
{
    if (_renderModeSet) return;
    manager.SetPlatformRenderMode(mode);
    _renderModeSet = true;
}

Try / catch

try
{
    manager.SetPlatformRenderMode(mode);
}
catch (InvalidOperationException ex) when (ex.Message == "Render mode already set.")
{
    // already configured - safe to ignore in idempotent setup paths
}

Prevention

When it happens

Trigger: Calling SetPlatformRenderMode more than once with any render mode argument.

Common situations: Custom host that configures render mode per request; integration code that sets it both at startup and again per-endpoint; a test fixture that re-initializes without a fresh manager.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/ff2795cb74c239ab. Report an issue: GitHub.