yewstack/yew · error
Event should have a target when dispatched
Error message
Event should have a target when dispatched
What it means
This panic is the `.expect()` on `Event::target()` in Yew 0.22's events guide, identical to the 0.21 listing. `web_sys::Event::target()` returns `Option<EventTarget>` because the DOM permits targetless events (constructed-but-undispatched events, `window`-dispatched events). Yew forwards the raw browser event to the `Callback<Event>`, so a None target makes the expect panic and aborts the WASM app. Genuine user-driven `change` events on an `<input>` always carry a target, so this is almost exclusively a test/synthetic-dispatch problem.
Source
Thrown at website/versioned_docs/version-0.22/concepts/html/events.mdx:155
Callback::from(move |e: Event| {
// When events are created the target is undefined, it's only
// when dispatched does the target get added.
let target: Option<EventTarget> = e.target();
// Events can bubble so this listener might catch events from child
// elements which are not of type HtmlInputElement
//highlight-next-line
let input = target.and_then(|t| t.dyn_into::<HtmlInputElement>().ok());
if let Some(input) = input {
input_value_handle.set(input.value());
}
})
};
let on_dangerous_change = Callback::from(move |e: Event| {
let target: EventTarget = e
.target()
.expect("Event should have a target when dispatched");
// You must KNOW target is a HtmlInputElement, otherwise
// the call to value would be Undefined Behaviour (UB).
// Here we are sure that this is input element so we can convert it to the appropriate type without checking
//highlight-next-line
input_value_handle.set(target.unchecked_into::<HtmlInputElement>().value());
});
html! {
<>
<label for="cautious-input">
{ "My cautious input:" }
<input onchange={on_cautious_change}
id="cautious-input"
type="text"
value={input_value.clone()}
/>
</label>
<label for="dangerous-input">View on GitHub (pinned to 0e4a05472f)
Solutions
- Handle the Option: `let Some(target) = e.target() else { return; };`
- Use `e.target_dyn_into::<HtmlInputElement>()` — presence check plus type check in one call, as shown later in the same guide
- Dispatch synthetic events from the real input element in tests so the target is populated
Example fix
// before
let target: EventTarget = e
.target()
.expect("Event should have a target when dispatched");
input_value_handle.set(target.unchecked_into::<HtmlInputElement>().value());
// after
if let Some(input) = e.target_dyn_into::<HtmlInputElement>() {
input_value_handle.set(input.value());
} Defensive patterns
Strategy: type-guard
Validate before calling
let on_dangerous_change = Callback::from(move |e: Event| {
let Some(target) = e.target() else {
return;
};
let _ = target;
}); Type guard
use web_sys::{Event, HtmlInputElement};
fn input_target(e: &Event) -> Option<HtmlInputElement> {
e.target_dyn_into::<HtmlInputElement>()
} Prevention
- Use target_dyn_into::<HtmlInputElement>() instead of target().expect() + unchecked_into
- In tests, dispatch change events from the input element so the target is populated
- Centralize event-target extraction helpers instead of repeating expects per handler
When it happens
Trigger: A `wasm-bindgen-test` invoking the `on_dangerous_change` callback with a hand-built `Event` (target None); dispatching `change` through `window.dispatchEvent`; event retargeting wrappers in test utilities.
Common situations: Copy-pasting the events.mdx `unchecked_into` recipe (line ~155) from the 0.22 docs into apps or tests; upgrading from Yew versions where handlers received typed event wrappers and now receive plain `Event`.
Related errors
- Event should have a target when dispatched
- Event should have a target when dispatched
- I'm sure this event has a target!
- mouse event doesn't have a target
- I'm sure this event has a target!
AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22).
Data as JSON: /api/errors/7f9eb609097cb766.
Report an issue: GitHub.