yewstack/yew · error
mouse event doesn't have a target
Error message
mouse event doesn't have a target
What it means
This panic is the `.expect("mouse event doesn't have a target")` on `e.target()` inside the mousemove closure from the web-sys guide (Yew 0.22 docs). `MouseEvent::target()` returns `Option<EventTarget>`; a handler attached with `set_onmousemove` on an element always receives real events with a target, so None only occurs for synthetic/programmatic events — e.g. a `MouseEvent` built with `MouseEvent::new` and passed to the closure directly in a test, never having been dispatched.
Source
Thrown at website/versioned_docs/version-0.22/concepts/basic-web-technologies/web-sys.mdx:172
version = "0.3"
# We need to enable all the web-sys features we want to use!
features = [
"console",
"Document",
"HtmlElement",
"MouseEvent",
"DomRect",
]
```
```rust ,no_run
use wasm_bindgen::{prelude::Closure, JsCast};
use web_sys::{console, Document, HtmlElement, MouseEvent};
let mousemove = Closure::<dyn Fn(MouseEvent)>::wrap(Box::new(|e| {
let rect = e
.target()
.expect("mouse event doesn't have a target")
.dyn_into::<HtmlElement>()
.expect("event target should be of type HtmlElement")
.get_bounding_client_rect();
let x = (e.client_x() as f64) - rect.left();
let y = (e.client_y() as f64) - rect.top();
console::log_1(&format!("Left? : {} ; Top? : {}", x, y).into());
}));
Document::new()
.expect("global document not set")
.get_element_by_id("mousemoveme")
.expect("element with id `mousemoveme` not present")
.unchecked_into::<HtmlElement>()
.set_onmousemove(mousemove.as_ref().dyn_ref());
// we now need to save the `mousemove` Closure so that when
// this event fires the closure is still in memory.
```View on GitHub (pinned to 0e4a05472f)
Solutions
- Replace the expect with `let Some(target) = e.target() else { return; };` so targetless events are skipped
- For coordinates relative to the tracked element, prefer `e.current_target()` — it is always the element you bound the handler to
- In tests, dispatch the mousemove from a real element (`el.dispatch_event(&MouseEvent::new().unwrap())`) so the target is populated
Example fix
// before
let rect = e
.target()
.expect("mouse event doesn't have a target")
.dyn_into::<HtmlElement>()
.expect("event target should be of type HtmlElement")
.get_bounding_client_rect();
// after
let rect = e
.current_target() // guaranteed: the element the handler is bound to
.dyn_into::<HtmlElement>()
.ok()?
.get_bounding_client_rect(); Defensive patterns
Strategy: validation
Validate before calling
let mousemove = Closure::<dyn Fn(MouseEvent)>::wrap(Box::new(|e| {
let Some(target) = e.target() else {
return; // skip targetless (synthetic) events
};
let _ = target;
})); Type guard
use wasm_bindgen::JsCast;
use web_sys::{EventTarget, HtmlElement, MouseEvent};
fn target_element(e: &MouseEvent) -> Option<HtmlElement> {
e.target()?.dyn_into::<HtmlElement>().ok()
} Prevention
- Use e.current_target() for coordinates relative to the tracked element — always present for handlers attached via set_onmousemove
- Skip targetless events early with let-else instead of expect
- In tests, dispatch mousemove from a real element rather than invoking the closure with a constructed MouseEvent
When it happens
Trigger: Unit-testing the closure by invoking it with `MouseEvent::new().unwrap()` (no dispatch, so target is None); forwarding MouseEvents through a custom event system that strips or never sets targets; dispatching on non-node dispatch objects.
Common situations: Copy-pasting the mouse-coordinate example from web-sys.mdx into tests or examples that synthesize events; adapting the closure to run in non-browser harnesses where event plumbing is simulated.
Related errors
- mouse event doesn't have a target
- I'm sure this event has a target!
- I'm sure this event has 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/9059ea04b190490c.
Report an issue: GitHub.