leptos-rs/leptos · error

A was not present

Error message

A was not present

What it means

An Either view was expected to contain variant A (e.g. via into_inner_a or A-extraction logic) but variant B was present. This indicates the Either's inner branch was not the one assumed — a logic mismatch between how the Either was constructed and how it is consumed.

Source

Thrown at tachys/src/view/either.rs:720

    fn into_owned(self) -> Self::Owned {
        EitherKeepAlive {
            a: self.a.map(|a| a.into_owned()),
            b: self.b.map(|b| b.into_owned()),
            show_b: self.show_b,
        }
    }
}

impl<A, B> Mountable for EitherKeepAliveState<A, B>
where
    A: Mountable,
    B: Mountable,
{
    fn unmount(&mut self) {
        if self.showing_b {
            self.b.as_mut().expect("B was not present").unmount();
        } else {
            self.a.as_mut().expect("A was not present").unmount();
        }
    }

    fn mount(
        &mut self,
        parent: &crate::renderer::types::Element,
        marker: Option<&crate::renderer::types::Node>,
    ) {
        if self.showing_b {
            self.b
                .as_mut()
                .expect("B was not present")
                .mount(parent, marker);
        } else {
            self.a
                .as_mut()
                .expect("A was not present")
                .mount(parent, marker);

View on GitHub (pinned to 32d20f6c9d)

Solutions

  1. Ensure the active side is always Some via the standard update/mount flow before unmounting.
  2. Make unmount idempotent by tracking whether the view is still mounted.
  3. In debug builds, assert (!showing_b implies a.is_some()) before unmount.

Example fix

// before
state.showing_b = true;
state.a = None;
state.showing_b = false;
state.unmount(); // panics: a is None
// after
state.a = Some(new_view_a);
state.showing_b = false;
state.unmount();
Defensive patterns

Strategy: validation

Validate before calling

if !state.showing_b && state.a.is_some() {
    state.unmount();
}

Type guard

fn a_unmountable<A, B>(state: &EitherKeepAliveState<A, B>) -> bool {
    state.showing_b || true /* a.is_some() */
}

Try / catch

std::panic::catch_unwind(|| state.unmount())
    .inspect_err(|_| eprintln!("unmount called while A branch slot was empty"));

Prevention

When it happens

Trigger: Calling unmount on an EitherKeepAliveState with showing_b == false and a == None — state never had the A view filled, or a was cleared by a switch to B while the flag was later reset.

Common situations: Double unmount of a conditional view; manual state construction missing the A view; switching branches then unmounting without letting the update path refill the new active side.

Related errors


AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01). Data as JSON: /api/errors/6fe2e2845b79811b. Report an issue: GitHub.