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 `ThemedButton` from Yew 0.23's contexts guide. `use_context::<Theme>()` returns None unless an ancestor in the Yew component tree rendered `<ContextProvider<Theme> context={(*ctx).clone()}>` — the role `ThemeContextProvider` plays in the same page. The button's own doc comment requires it to be a child of that provider; rendered anywhere else, the expect panics.

Source

Thrown at website/versioned_docs/version-0.23/concepts/contexts.mdx:144

}

/// The toolbar.
/// This component has access to the context
#[component]
pub fn Toolbar() -> Html {
    html! {
        <div>
            <ThemedButton />
        </div>
    }
}

/// Button placed in `Toolbar`.
/// As this component is a child of `ThemeContextProvider` in the component tree, it also has access
/// to the context.
#[component]
pub fn ThemedButton() -> Html {
    let theme = use_context::<Theme>().expect("no ctx found");

    html! {
        <button style={format!("background: {}; color: {};", theme.background, theme.foreground)}>
            { "Click me!" }
        </button>
    }
}
```

### Step 2: Consuming context

#### Function components

`use_context` hook is used to consume contexts in function components.
See [docs for use_context](https://yew-rs-api.web.app/next/yew/functional/fn.use_context.html) to learn more.

#### Struct components

View on GitHub (pinned to 0e4a05472f)

Solutions

  1. Wrap the consumer tree in `<ContextProvider<Theme> context={...}>` via `ThemeContextProvider`
  2. Verify provider and consumer use the exact same `Theme` type
  3. Replace the expect with `unwrap_or_default()` or a fallback `match` arm
  4. Mount the button inside the provider in tests

Example fix

// before
let theme = use_context::<Theme>().expect("no ctx found");

// after — default theme when no provider is present
let theme = use_context::<Theme>().unwrap_or_default();
html! {
    <button style={format!("background: {}; color: {};", theme.background, theme.foreground)}>
        { "Click me!" }
    </button>
}
Defensive patterns

Strategy: fallback

Validate before calling

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

// and make sure the tree renders:
// <ContextProvider<Theme> context={(*ctx).clone()}> <Toolbar> <ThemedButton/> </Toolbar> </ContextProvider<Theme>>

Prevention

When it happens

Trigger: Rendering `<ThemedButton/>` outside the `ThemeContextProvider` subtree; provider and consumer disagreeing on the context type (wrapper vs bare struct); provider unmounting on navigation while the button stays mounted.

Common situations: Reusing the guide's button in new routes not wrapped by the provider; refactors moving the provider; struct renames during Yew upgrades that split provider and consumer types.

Related errors


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