yewstack/yew · error
failed to prepare state
Error message
failed to prepare state
What it means
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.
Source
Thrown at packages/yew/src/functional/hooks/use_transitive_state/feat_ssr.rs:37
pub state_fn: RefCell<Option<F>>,
pub deps: Rc<D>,
}
impl<T, D, F> PreparedState for TransitiveStateBase<T, D, F>
where
D: Serialize + DeserializeOwned + PartialEq + 'static,
T: Serialize + DeserializeOwned + 'static,
F: 'static + FnOnce(Rc<D>) -> T,
{
fn prepare(&self) -> String {
let f = self.state_fn.borrow_mut().take().unwrap();
let state = f(self.deps.clone());
let state = bincode::serde::encode_to_vec(
(Some(&state), Some(&*self.deps)),
bincode::config::standard(),
)
.expect("failed to prepare state");
Base64::encode_string(&state)
}
}
#[doc(hidden)]
pub fn use_transitive_state<T, D, F>(
deps: D,
f: F,
) -> impl Hook<Output = SuspensionResult<Option<Rc<T>>>>
where
D: Serialize + DeserializeOwned + PartialEq + 'static,
T: Serialize + DeserializeOwned + 'static,
F: 'static + FnOnce(Rc<D>) -> T,
{
struct HookProvider<T, D, F>
where
D: Serialize + DeserializeOwned + PartialEq + 'static,View on GitHub (pinned to 0e4a05472f)
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)
Example fix
// CI guard mirroring what the hook encodes on the server
#[test]
fn transitive_state_encodes() {
let deps = sample_deps();
let state = build_state(&deps);
let bytes = bincode::serde::encode_to_vec(
(Some(&state), Some(&deps)),
bincode::config::standard(),
);
assert!(bytes.is_ok());
} Defensive patterns
Strategy: validation
Validate before calling
// Mirror the hook's encode in CI:
#[test]
fn transitive_state_encodes() {
let deps = sample_deps();
let state = build_state(&deps);
let bytes = bincode::serde::encode_to_vec(
(Some(&state), Some(&deps)),
bincode::config::standard(),
);
assert!(bytes.is_ok());
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to prepare state
- this hook takes 2 arguments but 1 argument was supplied
- this hook takes 2 arguments but 1 argument was supplied
- resolver not set on server-side LinkProvider
- failed to clone node.
AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22).
Data as JSON: /api/errors/bfce07fd33f06e34.
Report an issue: GitHub.