yewstack/yew · error

no ctx found

Error message

no ctx found

What it means

This panic is `use_context::<Theme>().expect("no ctx found")` in `ThemedButtonHOC` from Yew 0.23's HOC guide. The higher-order component consumes the theme via `use_context`, which returns `Option` and only finds a value when an ancestor rendered `<ContextProvider<Theme> context={...}>` — the guide's `ThemeContextProvider` does this. Rendering the HOC outside that provider subtree panics here.

Source

Thrown at website/versioned_docs/version-0.23/advanced-topics/struct-components/hoc.mdx:43

#[component]
pub fn App() -> Html {
    let ctx = use_state(|| Theme {
        foreground: "#000000".to_owned(),
        background: "#eeeeee".to_owned(),
    });

    html! {
        <ContextProvider<Theme> context={(*ctx).clone()}>
            <ThemedButtonHOC />
        </ContextProvider<Theme>>
    }
}

// highlight-start
#[component]
pub fn ThemedButtonHOC() -> Html {
    let theme = use_context::<Theme>().expect("no ctx found");

    html! {<ThemedButtonStructComponent {theme} />}
}
// highlight-end

#[derive(Properties, PartialEq)]
pub struct Props {
    pub theme: Theme,
}

struct ThemedButtonStructComponent;

impl Component for ThemedButtonStructComponent {
    type Message = ();
    type Properties = Props;

    fn create(_ctx: &Context<Self>) -> Self {
        Self

View on GitHub (pinned to 0e4a05472f)

Solutions

  1. Render `ThemedButtonHOC` inside `ThemeContextProvider` / `<ContextProvider<Theme> context={...}>`
  2. Confirm both sides use the identical `Theme` type
  3. Swap the expect for `unwrap_or_default()` or a match with a default theme so a missing provider degrades instead of crashing
  4. Mount the HOC within the provider in tests

Example fix

// before
pub fn ThemedButtonHOC() -> Html {
    let theme = use_context::<Theme>().expect("no ctx found");
    html! { <ThemedButtonStructComponent {theme} /> }
}

// after
#[hook]
fn use_theme() -> Theme {
    use_context::<Theme>().unwrap_or_default()
}

pub fn ThemedButtonHOC() -> Html {
    let theme = use_theme();
    html! { <ThemedButtonStructComponent {theme} /> }
}
Defensive patterns

Strategy: fallback

Validate before calling

#[hook]
fn use_theme() -> Theme {
    use_context::<Theme>().unwrap_or_default()
}

// consumers then never see None; providers stay in ThemeContextProvider at the tree root

Prevention

When it happens

Trigger: Mounting `<ThemedButtonHOC/>` with no `ContextProvider<Theme>` ancestor; provider publishing a different type than the HOC consumes; provider in a sibling subtree; provider unmounted on route change.

Common situations: Demos or tests extracting the HOC without its provider; refactors relocating `ThemeContextProvider`; context type renames across version upgrades desynchronizing provider and consumer.

Related errors


AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22). Data as JSON: /api/errors/8cf1a1f1a6f35f3c. Report an issue: GitHub.