{"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/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/PersistentState/ComponentStatePersistenceManager.cs#L188-L224","documentation":"During InferRenderModes (run when persisting against a composite/multi-store), the manager walks registered persistence callbacks. For each callback whose explicit RenderMode is null, it tries to infer the mode from the callback's Target when it is an IComponent. If the Target is not an IComponent and no explicit RenderMode was supplied at registration time, inference is impossible and the manager throws. The callback cannot be routed to the correct store(s) without a known render mode.","triggerScenarios":"Registering a persistence callback whose target is a non-component object (e.g., a service, a static method, or a lambda not bound to an IComponent) via PersistentComponentState.PersistAsJson or a similar API, then persisting through a composite store (a store implementing IEnumerable<IPersistentComponentStateStore>) which triggers InferRenderModes. The registration did not pass an explicit render mode.","commonSituations":"A service or helper class calls state.PersistAsJson(key, value) during prerendering in a Blazor Web App with multiple render modes (Server + WebAssembly). Persisting from a non-component subscriber (e.g., a PersistentValueProviderComponentSubscription whose backing object is not the component). Custom state-persistence extensions that register callbacks from services.","solutions":["Pass an explicit render mode when registering the callback from a non-component target, using the registration overload that accepts an IComponentRenderMode.","Move the persistence call so its callback Target is the IComponent instance (e.g., call from within a component's lifecycle method).","If the value genuinely applies to SSR only, register it through a single (non-composite) store path so InferRenderModes never runs."],"exampleFix":"// before: persist from a service with no render mode in a multi-store app\nstate.PersistAsJson(\"my-key\", value);\n\n// after: pass explicit render mode, or call from the component\nstate.PersistAsJson(\"my-key\", value, RenderMode.InteractiveServer);","handlingStrategy":"validation","validationCode":"// When persisting from a non-component, pass an explicit render mode.\nif (this is not IComponent)\n{\n    state.PersistAsJson(key, value, RenderMode.InteractiveServer);\n}\nelse\n{\n    state.PersistAsJson(key, value);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass an explicit render mode when persisting from services in multi-store apps.","Prefer persisting from within an IComponent so the mode can be inferred.","Use a single store for SSR-only persistence to bypass InferRenderModes."],"tags":["blazor","render-mode","persistence","multi-store"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}