{"record":{"id":"9059ea04b190490c","repo":"yewstack/yew","slug":"mouse-event-doesn-t-have-a-target-9059ea","errorCode":null,"errorMessage":"mouse event doesn't have a target","messagePattern":"mouse event doesn't have a target","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"website/versioned_docs/version-0.22/concepts/basic-web-technologies/web-sys.mdx","lineNumber":172,"sourceCode":"version = \"0.3\"\n# We need to enable all the web-sys features we want to use!\nfeatures = [\n    \"console\",\n    \"Document\",\n    \"HtmlElement\",\n    \"MouseEvent\",\n    \"DomRect\",\n]\n```\n\n```rust ,no_run\nuse wasm_bindgen::{prelude::Closure, JsCast};\nuse web_sys::{console, Document, HtmlElement, MouseEvent};\n\nlet mousemove = Closure::<dyn Fn(MouseEvent)>::wrap(Box::new(|e| {\n    let rect = e\n        .target()\n        .expect(\"mouse event doesn't have a target\")\n        .dyn_into::<HtmlElement>()\n        .expect(\"event target should be of type HtmlElement\")\n        .get_bounding_client_rect();\n    let x = (e.client_x() as f64) - rect.left();\n    let y = (e.client_y() as f64) - rect.top();\n    console::log_1(&format!(\"Left? : {} ; Top? : {}\", x, y).into());\n}));\n\nDocument::new()\n    .expect(\"global document not set\")\n    .get_element_by_id(\"mousemoveme\")\n    .expect(\"element with id `mousemoveme` not present\")\n    .unchecked_into::<HtmlElement>()\n    .set_onmousemove(mousemove.as_ref().dyn_ref());\n\n// we now need to save the `mousemove` Closure so that when\n// this event fires the closure is still in memory.\n```","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/yewstack/yew/blob/0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3/website/versioned_docs/version-0.22/concepts/basic-web-technologies/web-sys.mdx#L154-L190","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nlet rect = e\n    .target()\n    .expect(\"mouse event doesn't have a target\")\n    .dyn_into::<HtmlElement>()\n    .expect(\"event target should be of type HtmlElement\")\n    .get_bounding_client_rect();\n\n// after\nlet rect = e\n    .current_target() // guaranteed: the element the handler is bound to\n    .dyn_into::<HtmlElement>()\n    .ok()?\n    .get_bounding_client_rect();","handlingStrategy":"validation","validationCode":"let mousemove = Closure::<dyn Fn(MouseEvent)>::wrap(Box::new(|e| {\n    let Some(target) = e.target() else {\n        return; // skip targetless (synthetic) events\n    };\n    let _ = target;\n}));","typeGuard":"use wasm_bindgen::JsCast;\nuse web_sys::{EventTarget, HtmlElement, MouseEvent};\n\nfn target_element(e: &MouseEvent) -> Option<HtmlElement> {\n    e.target()?.dyn_into::<HtmlElement>().ok()\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["web-sys","events","mouse","option-expect","panic"],"backgroundTag":"event-target-missing","analyzedSha":"0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3","analyzedAt":"2026-08-22T21:16:31.212Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}