{"record":{"id":"3a25e0d3db5c0a48","repo":"yewstack/yew","slug":"resolver-not-set-on-server-side-linkprovider","errorCode":null,"errorMessage":"resolver not set on server-side LinkProvider","messagePattern":"resolver not set on server-side LinkProvider","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/yew-link/src/lib.rs","lineNumber":394,"sourceCode":"                Some(err_val) => {\n                    let e: T::Error = serde_json::from_value(err_val)\n                        .map_err(|e| LinkError::Internal(e.to_string()))?;\n                    Err(LinkError::Resolve(e))\n                }\n                None => Err(LinkError::Internal(\"unknown error\".into())),\n            },\n        }\n    }\n\n    #[cfg(feature = \"ssr\")]\n    async fn resolve_local<T: LinkedState>(\n        &self,\n        input: &T::Input,\n    ) -> Result<T, LinkError<T::Error>> {\n        let resolver = self\n            .resolver\n            .as_ref()\n            .expect(\"resolver not set on server-side LinkProvider\");\n        let req = LinkRequest {\n            type_key: T::TYPE_KEY.to_string(),\n            input: serde_json::to_value(input).map_err(|e| LinkError::Internal(e.to_string()))?,\n        };\n        match resolver.resolve_request(&req).await {\n            Ok(val) => serde_json::from_value(val).map_err(|e| LinkError::Internal(e.to_string())),\n            Err(err_val) => {\n                let e: T::Error = serde_json::from_value(err_val)\n                    .map_err(|e| LinkError::Internal(e.to_string()))?;\n                Err(LinkError::Resolve(e))\n            }\n        }\n    }\n}\n\n/// Wrapper so [`Resolver`] can be passed as a component prop.\n///\n/// Uses `Arc` internally so it is `Send` (required by `ServerRenderer::with_props`).","sourceCodeStart":376,"sourceCodeEnd":412,"githubUrl":"https://github.com/yewstack/yew/blob/0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3/packages/yew-link/src/lib.rs#L376-L412","documentation":"On SSR builds, LinkContextInner::resolve_local (packages/yew-link/src/lib.rs:394) unwraps the provider's optional resolver with .expect. The resolver is only populated when the server-side <LinkProvider> was given a resolver prop (LinkProviderProps.resolver, line 444); on wasm it is ignored. If a server render calls use_linked_state through a LinkProvider that has no resolver, this panic fires.","triggerScenarios":"Rendering with the ssr feature enabled (ServerRenderer) while <LinkProvider> only received an endpoint and no ResolverProp; building a LinkProviderProps by hand and leaving resolver as None; feature-flag drift where the server build takes the ssr branch of resolve_local.","commonSituations":"Configuring LinkProvider once for the client (endpoint only) and reusing those props for the server renderer; adding yew-link SSR to an existing client app and missing the server-side resolver wiring; upgrading yew-link where resolver became a required-for-SSR prop.","solutions":["Pass a ResolverProp to LinkProvider in the SSR tree: <LinkProvider resolver={ResolverProp(resolver)} endpoint={...}>{children}</LinkProvider>","Keep separate provider props for server and client: server = resolver (endpoint ignored), client = endpoint","If you cannot resolve locally on the server, disable the ssr feature so the hook does not take the resolve_local path"],"exampleFix":"// before\nlet props = LinkProviderProps { children, endpoint: AttrValue::from(\"/api/link\"), resolver: None, cache_capacity: 64 };\n\n// after\nlet resolver = Resolver::new(|req| Box::pin(async move { resolve_link(req).await }));\nlet props = LinkProviderProps { children, endpoint: AttrValue::from(\"/api/link\"), resolver: Some(resolver.into()), cache_capacity: 64 };","handlingStrategy":"validation","validationCode":"// build SSR provider props with a resolver, fail fast if it is missing\nlet resolver = Resolver::new(|req| Box::pin(async move { resolve_link(req).await }));\nlet props = LinkProviderProps {\n    children: Children::new(vec![/* app */]),\n    endpoint: AttrValue::from(\"/api/link\"),\n    resolver: Some(resolver.into()),\n    cache_capacity: 64,\n};\ndebug_assert!(props.resolver.is_some(), \"SSR LinkProvider needs a resolver\");","typeGuard":"// narrow on the prop before rendering the server tree\nfn has_ssr_resolver(props: &LinkProviderProps) -> bool { #[cfg(feature = \"ssr\")] { props.resolver.is_some() } #[cfg(not(feature = \"ssr\"))] { true } }","tryCatchPattern":null,"preventionTips":["Maintain separate provider props for server (resolver) and client (endpoint)","Add a debug_assert on the resolver before starting ServerRenderer","Run one SSR smoke test per app entry so a misconfigured provider panics in CI, not production"],"tags":["rust","ssr","yew-link","server-rendering","runtime-panic"],"backgroundTag":"missing-provider-config","analyzedSha":"0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3","analyzedAt":"2026-08-22T21:16:31.212Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}