yewstack/yew · error
I'm sure this event has a target!
Error message
I'm sure this event has a target!
What it means
This panic is the `.expect()` on `Event::target()` in the raw wasm-bindgen guide's `handle_event` (the setup for the `dyn_ref::<HtmlSelectElement>()` cast demonstration). `Event::target()` is an Option because the DOM allows targetless events — events built with `Event::new` and never dispatched, or dispatched on `window`/`document` in some synthetic flows. When the handler receives such an event, the expect panics before the casts are even attempted.
Source
Thrown at website/versioned_docs/version-0.22/concepts/basic-web-technologies/wasm-bindgen.mdx:146
`JsCast` provides both checked and unchecked methods of casting - so if at runtime if you are
unsure what type a certain object is, you can try to cast it, which returns possible failure types like
[`Option`](https://doc.rust-lang.org/std/option/enum.Option.html) and
[`Result`](https://doc.rust-lang.org/std/result/enum.Result.html).
A common example of this in [`web-sys`](./web-sys.mdx) is when you are trying to get the
target of an event. You might know what the target element is, but the
[`web_sys::Event`](https://wasm-bindgen.github.io/wasm-bindgen/api/web_sys/struct.Event.html) API will always return an [`Option<web_sys::EventTarget>`](https://wasm-bindgen.github.io/wasm-bindgen/api/web_sys/struct.Event.html#method.target).
You will need to cast it to the element type so you can call its methods.
```rust
// need to import the trait.
use wasm_bindgen::JsCast;
use web_sys::{Event, EventTarget, HtmlInputElement, HtmlSelectElement};
fn handle_event(event: Event) {
let target: EventTarget = event
.target()
.expect("I'm sure this event has a target!");
// maybe the target is a select element?
if let Some(select_element) = target.dyn_ref::<HtmlSelectElement>() {
// do something amazing here
return;
}
// if it wasn't a select element then I KNOW it's a input element!
let input_element: HtmlInputElement = target.unchecked_into();
}
```
The [`dyn_ref`](https://wasm-bindgen.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html#method.dyn_ref)
method is a checked cast that returns an `Option<&T>`, which means the original type
can be used again if the cast failed and thus returned `None`. The
[`dyn_into`](https://wasm-bindgen.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html#method.dyn_into)
method will consume `self`, as per convention for `into` methods in Rust, and the type returned is
`Result<T, Self>`. If the casting fails, the original `Self` value is returned in `Err`. You can try againView on GitHub (pinned to 0e4a05472f)
Solutions
- Handle the Option before casting: `let Some(target) = event.target() else { return; };`
- Keep the guide's `dyn_ref` casting pattern but drive it from the unwrapped target inside `if let` / `match` arms
- When you control dispatch, dispatch synthetic events from a concrete element so the target is set
Example fix
// before
let target: EventTarget = event
.target()
.expect("I'm sure this event has a target!");
// after
let Some(target) = event.target() else {
return; // targetless event (e.g. synthetic) — nothing to inspect
};
if let Some(select_element) = target.dyn_ref::<HtmlSelectElement>() {
// handle select target
return;
} Defensive patterns
Strategy: type-guard
Validate before calling
fn handle_event(event: Event) {
let Some(target) = event.target() else {
return; // targetless (synthetic) event — nothing to inspect
};
// safe to attempt type-specific handling on `target`
} Type guard
use wasm_bindgen::JsCast;
use web_sys::{EventTarget, HtmlSelectElement};
fn as_select(t: &EventTarget) -> Option<&HtmlSelectElement> {
t.dyn_ref::<HtmlSelectElement>()
} Prevention
- Never call expect() on Event::target(); treat Option as the normal case
- Prefer dyn_ref over dyn_into when you only need to read fields — it cannot fail loudly
- When synthesizing events in tests, always dispatch them from a concrete element so target is set
When it happens
Trigger: Calling `handle_event` with an `Event` constructed via `Event::new("change", &Object::new()).unwrap()` (target is None until dispatched); routing targetless synthetic events from a test harness or an event-bus library into this function.
Common situations: Copy-pasting the wasm-bindgen casting example into a real event listener or test; integrating with libraries that re-dispatch or forward `Event` objects; headless tests constructing events manually because no DOM interaction framework is set up.
Related errors
- I'm sure this event has a target!
- mouse event doesn't have a target
- mouse event doesn't have a target
- Event should have a target when dispatched
- event target should be of type HtmlElement
AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22).
Data as JSON: /api/errors/bf31eda6fd372270.
Report an issue: GitHub.