yewstack/yew · error
failed to prepare state
Error message
failed to prepare state
What it means
On the SSR path, use_prepared_state serializes (state, deps) with bincode so the value can be embedded in the page for hydration; this expect fires when that encode returns an error. Bincode only fails when the serde Serialize impl itself errors or the value cannot be represented - typical cases are custom Serialize impls returning Err for edge-case data and non-finite floats, which bincode's standard configuration rejects.
Source
Thrown at packages/yew/src/functional/hooks/use_prepared_state/mod.rs:136
#[cfg(feature = "hydration")]
pub has_buf: bool,
pub _marker: PhantomData<(T, D)>,
}
impl<T, D> PreparedState for PreparedStateBase<T, D>
where
D: Serialize + DeserializeOwned + PartialEq + 'static,
T: Serialize + DeserializeOwned + 'static,
{
#[cfg(feature = "ssr")]
fn prepare(&self) -> String {
use base64ct::{Base64, Encoding};
let state = bincode::serde::encode_to_vec(
(self.state.as_deref(), self.deps.as_deref()),
bincode::config::standard(),
)
.expect("failed to prepare state");
Base64::encode_string(&state)
}
}
}
#[cfg(any(feature = "hydration", feature = "ssr"))]
use feat_any_hydration_ssr::PreparedStateBase;
View on GitHub (pinned to 0e4a05472f)
Solutions
- Add a unit test that bincode-encodes realistic values of T and D (same call as the hook) and run it in CI
- Fix or replace the failing custom serde impls; prefer derived Serialize/Deserialize
- Sanitize non-finite floats (map to 0.0 or a string) before they enter prepared state
- Keep prepared state to plain data - numbers, strings, Vec, HashMap - and do complex computation in components
Example fix
// before: NaN slips into prepared state, bincode rejects it
let price = Price { value: input.unwrap_or(f64::NAN) };
// after: sanitize before the hook encodes it
let price = Price { value: input.filter(|v| v.is_finite()).unwrap_or(0.0) };
// CI guard mirroring the hook's encode:
#[test]
fn prepared_state_encodes() {
let bytes = bincode::serde::encode_to_vec(
(Some(Price { value: 0.0 }), Some(())),
bincode::config::standard(),
);
assert!(bytes.is_ok());
} Defensive patterns
Strategy: validation
Validate before calling
// Mirror the hook's encode in CI so bad types fail at test time, not in SSR:
#[test]
fn prepared_state_encodes() {
let bytes = bincode::serde::encode_to_vec(
(Some(sample_state()), Some(sample_deps())),
bincode::config::standard(),
);
assert!(bytes.is_ok());
} Prevention
- Prefer derived Serialize/Deserialize over hand-written impls for prepared state
- Sanitize NaN/Infinity floats before they reach use_prepared_state
- Keep prepared state limited to plain data types
When it happens
Trigger: use_prepared_state with a T or deps D containing a hand-written Serialize impl that returns an error for some values, NaN/Infinity floats, or constructs that bincode's standard config cannot encode - so SSR works locally but panics on production data.
Common situations: Custom Serialize/Deserialize impls for domain types; sensor or financial data containing NaN/infinite values; state types that grew unsupported constructs over time.
Related errors
- failed to prepare state
- failed to deserialize 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
AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22).
Data as JSON: /api/errors/48bdeb381de4a39c.
Report an issue: GitHub.