{"record":{"id":"f2b1c3dce8f2c08d","repo":"leptos-rs/leptos","slug":"internal-error-entered-unreachable-code-f2b1c3","errorCode":null,"errorMessage":"internal error: entered unreachable code","messagePattern":"internal error: entered unreachable code","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tachys/src/reactive_graph/mod.rs","lineNumber":276,"sourceCode":"            {\n                let mut fun = fun.clone();\n                move |prev| {\n                    /// codegen optimisation:\n                    fn get_guard(\n                        hook: &Option<Arc<dyn throw_error::ErrorHook>>,\n                    ) -> Option<throw_error::ResetErrorHookOnDrop>\n                    {\n                        hook.as_ref()\n                            .map(|h| throw_error::set_error_hook(Arc::clone(h)))\n                    }\n                    let _guard = get_guard(&hook);\n\n                    let value = fun.invoke();\n                    if let Some(mut state) = prev {\n                        value.rebuild(&mut state);\n                        state\n                    } else {\n                        unreachable!()\n                    }\n                }\n            },\n            async move { fun.invoke().hydrate_async(&cursor, &position).await },\n        )\n        .await\n        .into()\n    }\n\n    fn into_owned(self) -> Self::Owned {\n        self\n    }\n}\n\nimpl<F, V> AddAnyAttr for F\nwhere\n    F: ReactiveFunction<Output = V>,\n    V: RenderHtml + 'static,","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/leptos-rs/leptos/blob/32d20f6c9d517451d77beb68d88c7716823dac41/tachys/src/reactive_graph/mod.rs#L258-L294","documentation":"During `hydrate_async` of a reactive view fragment, tachys builds a `RenderEffect::new_with_async_value` whose closure asserts `prev` is `Some` (the previously rendered sub-view state used by `value.rebuild`). The panic means the effect closure ran while the async initial value had not resolved (slot still `None`) or after the value was taken — the reactive fragment re-rendered before its seed state existed.","triggerScenarios":"A reactive function inside a `<Suspense>`/async-hydrated fragment updates (signal fires) before `hydrate_async`'s future resolves and stores the initial view state; or the fragment is rebuilt/reset while the async value is pending.","commonSituations":"SSR + async hydration where a global signal changes during initial load (e.g. router navigation, websocket push) before hydration completes; Suspense fallback swapping in the resolved branch and immediately re-running the effect.","solutions":["Delay signal updates until after async hydration completes (e.g. run updates in an effect spawned after `hydrate` returns, or gate the signal source on a `hydrated` flag).","Avoid rapid branch swaps (`Show`/`Either`) around async-hydrated reactive fragments during initial load.","Upgrade leptos/tachys — later releases addressed `new_with_async_value` prev-value races.","Reproduce minimally and report to the Leptos tracker if stock components trigger it."],"exampleFix":"// before: signal updated during hydration\ncreate_effect(move |_| { data.update(...); }); // may run pre-hydration\n// after: gate until hydrated\nlet hydrated = RwSignal::new(false);\ncreate_effect(move |_| { if hydrated.get() { data.update(...); } });\n// set hydrated = true after view hydrates/mounts","handlingStrategy":"fallback","validationCode":"// Block reactive fragment updates until async hydration completes\nlet hydrated = RwSignal::new(false);\n// after hydrate_async resolves in your bootstrap:\nhydrated.set(true);\ncreate_effect(move |_| {\n    if !hydrated.get() { return; }\n    let _ = reactive_fragment_signal.get();\n});","typeGuard":"fn fragment_state_ready(prev: &Option<FragmentState>) -> bool { prev.is_some() }","tryCatchPattern":"// Wrap hydration bootstrap with catch_unwind + fallback\nlet result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    futures::executor::block_on(view.hydrate_async(...))\n}));\nif result.is_err() { render_client_fallback(); }","preventionTips":["Never write signals bound to a Suspense fragment before it resolves","Queue post-hydration updates via queue_microtask after mount returns","Avoid router navigation racing initial async hydration","Test SSR+hydration flows with signals that fire during load"],"tags":["panic","reactivity","async-hydration","suspense","leptos"],"backgroundTag":"unreachable-effect-previous-state-panicked","analyzedSha":"32d20f6c9d517451d77beb68d88c7716823dac41","analyzedAt":"2026-09-01T18:55:42.580Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}