{"record":{"id":"51584d082f29b35d","repo":"leptos-rs/leptos","slug":"rendering-a-to-html-without-filling-it","errorCode":null,"errorMessage":"rendering A to HTML without filling it","messagePattern":"rendering A to HTML without filling it","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tachys/src/view/either.rs","lineNumber":606,"sourceCode":"        buf: &mut String,\n        position: &mut Position,\n        escape: bool,\n        mark_branches: bool,\n        extra_attrs: Vec<AnyAttribute>,\n    ) {\n        if self.show_b {\n            self.b\n                .expect(\"rendering B to HTML without filling it\")\n                .to_html_with_buf(\n                    buf,\n                    position,\n                    escape,\n                    mark_branches,\n                    extra_attrs,\n                );\n        } else {\n            self.a\n                .expect(\"rendering A to HTML without filling it\")\n                .to_html_with_buf(\n                    buf,\n                    position,\n                    escape,\n                    mark_branches,\n                    extra_attrs,\n                );\n        }\n    }\n\n    fn to_html_async_with_buf<const OUT_OF_ORDER: bool>(\n        self,\n        buf: &mut StreamBuilder,\n        position: &mut Position,\n        escape: bool,\n        mark_branches: bool,\n        extra_attrs: Vec<AnyAttribute>,\n    ) where","sourceCodeStart":588,"sourceCodeEnd":624,"githubUrl":"https://github.com/leptos-rs/leptos/blob/32d20f6c9d517451d77beb68d88c7716823dac41/tachys/src/view/either.rs#L588-L624","documentation":"Mirror of the B-side panic: when show_b is false, EitherKeepAliveState renders self.a, which must contain the A view. This panic means the state says branch A is shown but the A slot is None. The Option is an internal invariant — exactly one side is filled — and rendering hit the empty side.","triggerScenarios":"Calling to_html_with_buf on an EitherKeepAliveState with show_b == false and a == None — state constructed/mutated without filling the A view, then server-rendered.","commonSituations":"Manual construction of EitherKeepAliveState for SSR tests; a state that was moved into branch B (a set to None) but whose show_b flag was reset to false without re-filling a.","solutions":["Refill the a slot before flipping showing_b back to false.","Construct the state through its normal API so the active view is always stored.","Add a debug assertion in your code that (showing_b == b.is_some()) && (!showing_b || a.is_none()) before rendering."],"exampleFix":"// before\nstate.showing_b = false; // a is still None\nstate.to_html_with_buf(...); // panics\n// after\nstate.a = Some(view_a);\nstate.showing_b = false;\nstate.to_html_with_buf(...);","handlingStrategy":"validation","validationCode":"if !state.showing_b && state.a.is_none() {\n    return Err(\"A branch flag set but a view is None\");\n}\nstate.to_html_with_buf(&mut buf, position, escape, mark_branches, extra_attrs);","typeGuard":"fn a_side_filled<A, B>(state: &EitherKeepAliveState<A, B>) -> bool {\n    state.showing_b || true /* replace with a.is_some() accessor */\n}","tryCatchPattern":"std::panic::catch_unwind(|| state.to_html_with_buf(&mut buf, position, escape, mark_branches, extra_attrs))\n    .inspect_err(|_| eprintln!(\"EitherKeepAliveState had unfilled A branch during SSR\"));","preventionTips":["Refill the a slot before flipping showing_b back to false.","Only switch branches through the view's update path.","Assert state completeness before server-side rendering.","Avoid shared mutation of the state from multiple code paths."],"tags":["ssr","html-rendering","either-view","panic","tachys"],"backgroundTag":"unfilled-either-branch","analyzedSha":"32d20f6c9d517451d77beb68d88c7716823dac41","analyzedAt":"2026-09-01T18:55:42.580Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}