{"record":{"id":"4b1d3943572b7d54","repo":"dotnet/aspnetcore","slug":"the-registered-callback-registration-callback-met","errorCode":null,"errorMessage":"The registered callback {registration.Callback.Method.Name} must be associated with a component or define an explicit render mode type during registration.","messagePattern":"The registered callback (.+?) must be associated with a component or define an explicit render mode type during registration\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/PersistentState/ComponentStatePersistenceManager.cs","lineNumber":206,"sourceCode":"            }\n\n            if (registration.Callback.Target is IComponent component)\n            {\n                var componentRenderMode = renderer.GetComponentRenderMode(component);\n                if (componentRenderMode != null)\n                {\n                    _registeredCallbacks[i] = new PersistComponentStateRegistration(registration.Callback, componentRenderMode);\n                }\n                else\n                {\n                    // If we can't find a render mode, it's an SSR only component and we don't need to\n                    // persist its state at all.\n                    _registeredCallbacks[i] = default;\n                }\n                continue;\n            }\n\n            throw new InvalidOperationException(\n                $\"The registered callback {registration.Callback.Method.Name} must be associated with a component or define\" +\n                $\" an explicit render mode type during registration.\");\n        }\n    }\n\n    internal Task<bool> TryPauseAsync(IPersistentComponentStateStore store)\n    {\n        List<Task<bool>>? pendingCallbackTasks = null;\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];","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Components/src/PersistentState/ComponentStatePersistenceManager.cs#L188-L224","documentation":"Thrown by ComponentStatePersistenceManager.InferRenderModes when a registered persisting callback has RenderMode == null (no explicit render mode passed to RegisterOnPersisting) and its Callback.Target is not an IComponent, so the renderer cannot infer a render mode from an owning component. This matters only in multi-store (composite) scenarios - e.g. a Blazor Web App with InteractiveAuto - where the framework must route each callback to the correct store (Server vs WebAssembly).","triggerScenarios":"state.RegisterOnPersisting(callback) where callback is a lambda whose captured Target is a service or a static method (not a component), used in an app with multiple persistent state stores, without passing an explicit IComponentRenderMode.","commonSituations":"Persisting state from an injected service via a lambda (() => service.Persist()) in a Blazor Web App with global Auto interactivity; upgrading a Server-only app to Auto where an existing service-based callback now fails; registering a persist callback from a non-component host.","solutions":["Pass an explicit render mode to RegisterOnPersisting, e.g. RegisterOnPersisting(callback, RenderMode.InteractiveWebAssembly) or InteractiveServer as appropriate.","Register the callback from inside a component so its Target is the component and the render mode can be inferred.","For persistent services, use [PersistentState] properties plus AddPersistentService<T> and specify the render mode at registration.","If the callback genuinely belongs to no render mode, scope it to a single-store scenario instead of a composite store."],"exampleFix":"// before (Auto render mode, service-based lambda)\n_state.RegisterOnPersisting(() => PersistMyService());\n\n// after\n_state.RegisterOnPersisting(() => PersistMyService(), RenderMode.InteractiveWebAssembly);","handlingStrategy":"validation","validationCode":"// When registering a persist callback from a non-component (service/lambda) target\n// in a composite-store (Auto) app, always pass an explicit render mode:\nPersistentComponentState RegisterPersist(PersistentComponentState state,\n    Func<Task> callback, IComponentRenderMode mode)\n    => state.RegisterOnPersisting(callback, mode) is var _\n        ? throw null! // placeholder; real usage below\n        : null!;\n\n// Real usage:\n// state.RegisterOnPersisting(PersistService, RenderMode.InteractiveWebAssembly);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass an explicit IComponentRenderMode when registering a service/lambda-based persist callback in Auto or multi-store apps.","Register persist callbacks from inside a component when possible so inference works.","For persistent services, use [PersistentState] + AddPersistentService<T> and specify render mode at registration.","When upgrading a Server-only app to Auto, audit all service-based RegisterOnPersisting calls and add explicit render modes."],"tags":["blazor","component-state","render-mode","persistence","auto","interactivity"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}