{"record":{"id":"3f0179d8190f8e95","repo":"leptos-rs/leptos","slug":"unrecoverable-hydration-error-please-read-the-err","errorCode":null,"errorMessage":"Unrecoverable hydration error. Please read the error message directly above this for more details.","messagePattern":"Unrecoverable hydration error\\. Please read the error message directly above this for more details\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"tachys/src/hydration.rs","lineNumber":184,"sourceCode":"    {\n        let hydrating = CURRENTLY_HYDRATING\n            .take()\n            .map(|n| n.to_string())\n            .unwrap_or_else(|| \"{unknown}\".to_string());\n        web_sys::console::error_3(\n            &wasm_bindgen::JsValue::from_str(&format!(\n                \"A hydration error occurred while trying to hydrate an \\\n                 element defined at {hydrating}.\\n\\nThe framework expected an \\\n                 HTML <{tag_name}> element, but found this instead: \",\n            )),\n            &node,\n            &wasm_bindgen::JsValue::from_str(\n                \"\\n\\nThe hydration mismatch may have occurred slightly \\\n                 earlier, but this is the first time the framework found a \\\n                 node of an unexpected type.\",\n            ),\n        );\n        panic!(\n            \"Unrecoverable hydration error. Please read the error message \\\n             directly above this for more details.\"\n        );\n    }\n}\n\npub(crate) fn failed_to_cast_marker_node(node: Node) -> Comment {\n    #[cfg(not(any(debug_assertions, leptos_debuginfo)))]\n    {\n        _ = node;\n        unreachable!();\n    }\n    #[cfg(any(debug_assertions, leptos_debuginfo))]\n    {\n        let hydrating = CURRENTLY_HYDRATING\n            .take()\n            .map(|n| n.to_string())\n            .unwrap_or_else(|| \"{unknown}\".to_string());","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/leptos-rs/leptos/blob/32d20f6c9d517451d77beb68d88c7716823dac41/tachys/src/hydration.rs#L166-L202","documentation":"During client-side hydration, tachys attempts to cast an existing DOM node to the expected element type; if the node's type does not match what server rendering produced, hydration cannot continue safely. The framework logs detailed mismatch info via console.error/warn, then panics because proceeding would leave the app in an inconsistent state.","triggerScenarios":"Calling hydrate (or inner_1 during traversal) where a DOM node fails the element type cast — e.g. server emitted <div> but client view expects <span>, or conditional/fragment structure shifted between server and client output.","commonSituations":"Server HTML generated by a different view tree than the client's first render (feature flags, platform-specific branches, nondeterministic data); missing or mismatched HydrationScript/keys; editing server-rendered HTML by hand.","solutions":["Make the server and client render the identical view tree for the initial HTML (same branches, same ordering).","Remove or fix conditional logic that diverges between SSR and hydration (e.g. cfg!, platform checks, time-based values).","Check the console message printed directly above the panic to locate the actual mismatch point and align the element types.","Ensure the ssr and hydrate feature sets match between the server and client builds."],"exampleFix":"// before\n#[cfg(feature = \"ssr\")]\nview! { <div>{\"server only\"}</div> }\n#[cfg(not(feature = \"ssr\"))]\nview! { <span>{\"client only\"}</span> }\n// after\nview! { <div>{\"shared\"}</div> }","handlingStrategy":"validation","validationCode":"// Before hydrating, compare a checksum of server HTML structure vs client view\nif !cfg!(feature = \"ssr\") || !cfg!(feature = \"hydrate\") { panic!(\"build must enable matching ssr/hydrate features\"); }","typeGuard":"fn is_element_of(node: &web_sys::Node, tag: &str) -> bool { node.dyn_ref::<web_sys::Element>().map(|e| e.tag_name().eq_ignore_ascii_case(tag)).unwrap_or(false) }","tryCatchPattern":"std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| hydrate_view())); // fall back to client render on hydration panic","preventionTips":["Render identical view trees on server and client for the initial HTML.","Keep ssr and hydrate feature flags in lockstep across builds.","Avoid platform/time/locale-dependent values in the initial render.","Never hand-edit or transform server-rendered HTML before hydration."],"tags":["hydration","ssr","dom-mismatch"],"backgroundTag":"hydration-mismatch","analyzedSha":"32d20f6c9d517451d77beb68d88c7716823dac41","analyzedAt":"2026-09-01T18:55:42.580Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}