{"record":{"id":"bfce07fd33f06e34","repo":"yewstack/yew","slug":"failed-to-prepare-state-bfce07","errorCode":null,"errorMessage":"failed to prepare state","messagePattern":"failed to prepare state","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/yew/src/functional/hooks/use_transitive_state/feat_ssr.rs","lineNumber":37,"sourceCode":"    pub state_fn: RefCell<Option<F>>,\n    pub deps: Rc<D>,\n}\n\nimpl<T, D, F> PreparedState for TransitiveStateBase<T, D, F>\nwhere\n    D: Serialize + DeserializeOwned + PartialEq + 'static,\n    T: Serialize + DeserializeOwned + 'static,\n    F: 'static + FnOnce(Rc<D>) -> T,\n{\n    fn prepare(&self) -> String {\n        let f = self.state_fn.borrow_mut().take().unwrap();\n        let state = f(self.deps.clone());\n\n        let state = bincode::serde::encode_to_vec(\n            (Some(&state), Some(&*self.deps)),\n            bincode::config::standard(),\n        )\n        .expect(\"failed to prepare state\");\n\n        Base64::encode_string(&state)\n    }\n}\n\n#[doc(hidden)]\npub fn use_transitive_state<T, D, F>(\n    deps: D,\n    f: F,\n) -> impl Hook<Output = SuspensionResult<Option<Rc<T>>>>\nwhere\n    D: Serialize + DeserializeOwned + PartialEq + 'static,\n    T: Serialize + DeserializeOwned + 'static,\n    F: 'static + FnOnce(Rc<D>) -> T,\n{\n    struct HookProvider<T, D, F>\n    where\n        D: Serialize + DeserializeOwned + PartialEq + 'static,","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/yewstack/yew/blob/0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3/packages/yew/src/functional/hooks/use_transitive_state/feat_ssr.rs#L19-L55","documentation":"On the SSR path, use_transitive_state serializes (Some(&state), Some(&deps)) with bincode before embedding the value in the page; this expect fires when that encode fails. Bincode fails only when the serde Serialize impl of the state or deps errors or the value cannot be represented (custom impls returning Err, non-finite floats) - the same failure class as use_prepared_state's prepare panic, just on the transitive-state hook.","triggerScenarios":"use_transitive_state(deps, f) where the state produced by f or the deps contain a custom Serialize impl that errors for certain values, NaN/Infinity floats, or types that bincode's standard configuration cannot encode.","commonSituations":"Hand-rolled serde impls that assume valid input; runtime-only edge values (NaN, infinity) never exercised by local tests; state types that evolved to include unsupported constructs.","solutions":["Add a bincode round-trip unit test for representative state+deps values and run it in CI","Fix or replace failing custom Serialize impls with derived ones","Sanitize non-finite floats before they enter transitive state","Keep transitive state to plain data types (numbers, strings, Vec, HashMap)"],"exampleFix":"// CI guard mirroring what the hook encodes on the server\n#[test]\nfn transitive_state_encodes() {\n    let deps = sample_deps();\n    let state = build_state(&deps);\n    let bytes = bincode::serde::encode_to_vec(\n        (Some(&state), Some(&deps)),\n        bincode::config::standard(),\n    );\n    assert!(bytes.is_ok());\n}","handlingStrategy":"validation","validationCode":"// Mirror the hook's encode in CI:\n#[test]\nfn transitive_state_encodes() {\n    let deps = sample_deps();\n    let state = build_state(&deps);\n    let bytes = bincode::serde::encode_to_vec(\n        (Some(&state), Some(&deps)),\n        bincode::config::standard(),\n    );\n    assert!(bytes.is_ok());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer derived serde impls for transitive state and deps","Reject or sanitize non-finite floats before they enter the state","Round-trip test state and deps through bincode whenever their types change"],"tags":["ssr","bincode","serialization","use-transitive-state"],"backgroundTag":"serialization-failed","analyzedSha":"0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3","analyzedAt":"2026-08-22T21:16:31.212Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}