{"record":{"id":"541d0fcbd67c5c43","repo":"leptos-rs/leptos","slug":"b-was-not-present","errorCode":null,"errorMessage":"B was not present","messagePattern":"B was not present","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tachys/src/view/either.rs","lineNumber":718,"sourceCode":"    }\n\n    fn into_owned(self) -> Self::Owned {\n        EitherKeepAlive {\n            a: self.a.map(|a| a.into_owned()),\n            b: self.b.map(|b| b.into_owned()),\n            show_b: self.show_b,\n        }\n    }\n}\n\nimpl<A, B> Mountable for EitherKeepAliveState<A, B>\nwhere\n    A: Mountable,\n    B: Mountable,\n{\n    fn unmount(&mut self) {\n        if self.showing_b {\n            self.b.as_mut().expect(\"B was not present\").unmount();\n        } else {\n            self.a.as_mut().expect(\"A was not present\").unmount();\n        }\n    }\n\n    fn mount(\n        &mut self,\n        parent: &crate::renderer::types::Element,\n        marker: Option<&crate::renderer::types::Node>,\n    ) {\n        if self.showing_b {\n            self.b\n                .as_mut()\n                .expect(\"B was not present\")\n                .mount(parent, marker);\n        } else {\n            self.a\n                .as_mut()","sourceCodeStart":700,"sourceCodeEnd":736,"githubUrl":"https://github.com/leptos-rs/leptos/blob/32d20f6c9d517451d77beb68d88c7716823dac41/tachys/src/view/either.rs#L700-L736","documentation":"EitherKeepAliveState::unmount unmounts the stored B view when showing_b is true, unwrapping self.b. This panic means the client-side state claims branch B is mounted but the B view was never stored (b is None), so there is nothing to unmount. It indicates the state was built or mutated outside the library's mount/rebuild flow.","triggerScenarios":"Calling unmount on an EitherKeepAliveState with showing_b == true but b == None — e.g. a state created with an empty B slot, or double-unmount after a switch cleared b.","commonSituations":"Calling unmount twice on the same state; manually constructing EitherKeepAliveState for client-side use; reactive teardown running after the branch already switched (b moved out).","solutions":["Only unmount states that went through mount(); track a mounted flag yourself for idempotent teardown.","Fill b = Some(view_b) whenever showing_b = true in hand-built state.","Avoid mutating EitherKeepAliveState fields directly; use the EitherKeepAlive view's update path."],"exampleFix":"// before\nif !state.mounted { state.unmount(); } // panics when b is None\n// after\nif state.mounted && state.b.is_some() { state.unmount(); state.mounted = false; }","handlingStrategy":"validation","validationCode":"if state.showing_b && state.b.is_some() {\n    state.unmount();\n}","typeGuard":"fn can_unmount<A, B>(state: &EitherKeepAliveState<A, B>) -> bool {\n    if state.showing_b { true /* b.is_some() */ } else { true /* a.is_some() */ }\n}","tryCatchPattern":"std::panic::catch_unwind(|| state.unmount())\n    .inspect_err(|_| eprintln!(\"attempted to unmount an EitherKeepAliveState with unfilled active branch\"));","preventionTips":["Only unmount states that previously went through mount().","Track a mounted flag for idempotent teardown.","Never mutate showing_b/b fields directly.","Run double-unmount tests to catch non-idempotent cleanup."],"tags":["client-side","unmount","either-view","panic","lifecycle"],"backgroundTag":"unfilled-either-branch","analyzedSha":"32d20f6c9d517451d77beb68d88c7716823dac41","analyzedAt":"2026-09-01T18:55:42.580Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}