yewstack/yew · error
event target should be of type HtmlElement
Error message
event target should be of type HtmlElement
What it means
This panic is `.dyn_into::<HtmlElement>().expect("event target should be of type HtmlElement")` in the web-sys mousemove example. `JsCast::dyn_into` returns `Result<HtmlElement, EventTarget>`; it errors when the target's underlying JS value is not an `HtmlElement` instance. The example assumes `e.target()` is the tracked `#mousemoveme` element, but the target is the deepest node under the pointer: attaching the listener to `document`/`window` makes the target a Document (not HtmlElement), and hovering SVG children yields `SvgElement`, which is also not `HtmlElement`.
Source
Thrown at website/versioned_docs/version-0.22/concepts/basic-web-technologies/web-sys.mdx:174
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.
```
This version is much more verbose, but you will probably notice part of that is because of failureView on GitHub (pinned to 0e4a05472f)
Solutions
- Replace `dyn_into(...).expect(...)` with `target.dyn_ref::<HtmlElement>()` inside an `if let` and skip non-element targets
- Use `e.current_target()` instead of `e.target()` — it is always the element you attached the handler to, so the cast is sound
- If you intentionally listen on document, branch on the concrete type: `match target.dyn_into() { Ok(el) => ..., Err(_) => ... }`
Example fix
// before
.dyn_into::<HtmlElement>()
.expect("event target should be of type HtmlElement")
.get_bounding_client_rect();
// after
let rect = e
.current_target()
.dyn_into::<HtmlElement>()
.ok()?
.get_bounding_client_rect();
// or, when you really need the hit element:
// if let Some(el) = e.target().and_then(|t| t.dyn_ref::<HtmlElement>().map(|el| el.get_bounding_client_rect())) { ... } Defensive patterns
Strategy: type-guard
Validate before calling
let rect = {
let t = e.current_target(); // the element this handler is bound to
if !t.is_instance_of::<web_sys::HtmlElement>() {
return;
}
t.unchecked_ref::<web_sys::HtmlElement>().get_bounding_client_rect()
}; Type guard
use wasm_bindgen::JsCast;
use web_sys::{EventTarget, HtmlElement};
fn is_html_element(t: &EventTarget) -> bool {
t.is_instance_of::<HtmlElement>()
} Prevention
- Prefer current_target() over target() when you need the element the listener is attached to
- Use dyn_ref::<HtmlElement>() + if-let instead of dyn_into().expect()
- Remember SVG/MathML hit targets are SvgElement/MathMLElement, not HtmlElement
- When binding to document or window, branch on the concrete target type instead of assuming HtmlElement
When it happens
Trigger: Attaching `onmousemove` to `document` or `window` instead of an element (target becomes Document/Window); the pointer moving over an `<svg>`/`<math>` descendant, making the target an `SvgElement`/`MathMLElement`; synthetic events dispatched on document in tests.
Common situations: Adapting the web-sys.mdx coordinate snippet to track the whole page (so developers bind on `document`); graphics-heavy apps with SVG icons inside the tracked region; headless tests dispatching on non-element nodes.
Related errors
- event target should be of type HtmlElement
- I'm sure this event has a target!
- mouse event doesn't have a target
- I'm sure this event has a target!
- mouse event doesn't have a target
AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22).
Data as JSON: /api/errors/6815d8728ee99f54.
Report an issue: GitHub.