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("Event should have a target when dispatched")` on `Event::target()` in Yew 0.23's events guide, same listing as 0.21/0.22. `Event::target()` returns `Option<EventTarget>`; the DOM permits targetless events (constructed but undispatched, or window-dispatched), and Yew hands the raw browser event to the `Callback<Event>`. A None target panics here. Real user-driven `change` events on the `<input>` always have a target, so this panic indicates synthetic or test-driven events.
Source
Thrown at website/versioned_docs/version-0.23/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; };`
- Prefer `e.target_dyn_into::<HtmlInputElement>()` (presence + type check, as the same guide teaches)
- Dispatch test events from the real input element
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>() — it replaces both the target expect and the unchecked_into UB risk
- Dispatch synthetic change events from the input element in tests
- Keep event helpers centralized so handlers never inline expect chains
When it happens
Trigger: Tests calling the `on_dangerous_change` callback with an `Event::new(...)` value (target None); dispatching `change` on `window` via `dispatchEvent`; retargeted events from shadow-DOM test utilities.
Common situations: Copy-pasting the events.mdx `unchecked_into` recipe (line ~155) from the 0.23 docs; headless test suites synthesizing input events.
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/a2e3c250cd2a06a4.
Report an issue: GitHub.