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

  1. Add a bincode round-trip unit test for representative state+deps values and run it in CI
  2. Fix or replace failing custom Serialize impls with derived ones
  3. Sanitize non-finite floats before they enter transitive state
  4. 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

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


AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22). Data as JSON: /api/errors/bfce07fd33f06e34. Report an issue: GitHub.