{"record":{"id":"7f9eb609097cb766","repo":"yewstack/yew","slug":"event-should-have-a-target-when-dispatched-7f9eb6","errorCode":null,"errorMessage":"Event should have a target when dispatched","messagePattern":"Event should have a target when dispatched","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"website/versioned_docs/version-0.22/concepts/html/events.mdx","lineNumber":155,"sourceCode":"        Callback::from(move |e: Event| {\n            // When events are created the target is undefined, it's only\n            // when dispatched does the target get added.\n            let target: Option<EventTarget> = e.target();\n            // Events can bubble so this listener might catch events from child\n            // elements which are not of type HtmlInputElement\n            //highlight-next-line\n            let input = target.and_then(|t| t.dyn_into::<HtmlInputElement>().ok());\n\n            if let Some(input) = input {\n                input_value_handle.set(input.value());\n            }\n        })\n    };\n\n    let on_dangerous_change = Callback::from(move |e: Event| {\n        let target: EventTarget = e\n            .target()\n            .expect(\"Event should have a target when dispatched\");\n        // You must KNOW target is a HtmlInputElement, otherwise\n        // the call to value would be Undefined Behaviour (UB).\n        // Here we are sure that this is input element so we can convert it to the appropriate type without checking\n        //highlight-next-line\n        input_value_handle.set(target.unchecked_into::<HtmlInputElement>().value());\n    });\n\n    html! {\n        <>\n            <label for=\"cautious-input\">\n                { \"My cautious input:\" }\n                <input onchange={on_cautious_change}\n                    id=\"cautious-input\"\n                    type=\"text\"\n                    value={input_value.clone()}\n                />\n            </label>\n            <label for=\"dangerous-input\">","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/yewstack/yew/blob/0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3/website/versioned_docs/version-0.22/concepts/html/events.mdx#L137-L173","documentation":"This panic is the `.expect()` on `Event::target()` in Yew 0.22's events guide, identical to the 0.21 listing. `web_sys::Event::target()` returns `Option<EventTarget>` because the DOM permits targetless events (constructed-but-undispatched events, `window`-dispatched events). Yew forwards the raw browser event to the `Callback<Event>`, so a None target makes the expect panic and aborts the WASM app. Genuine user-driven `change` events on an `<input>` always carry a target, so this is almost exclusively a test/synthetic-dispatch problem.","triggerScenarios":"A `wasm-bindgen-test` invoking the `on_dangerous_change` callback with a hand-built `Event` (target None); dispatching `change` through `window.dispatchEvent`; event retargeting wrappers in test utilities.","commonSituations":"Copy-pasting the events.mdx `unchecked_into` recipe (line ~155) from the 0.22 docs into apps or tests; upgrading from Yew versions where handlers received typed event wrappers and now receive plain `Event`.","solutions":["Handle the Option: `let Some(target) = e.target() else { return; };`","Use `e.target_dyn_into::<HtmlInputElement>()` — presence check plus type check in one call, as shown later in the same guide","Dispatch synthetic events from the real input element in tests so the target is populated"],"exampleFix":"// before\nlet target: EventTarget = e\n    .target()\n    .expect(\"Event should have a target when dispatched\");\ninput_value_handle.set(target.unchecked_into::<HtmlInputElement>().value());\n\n// after\nif let Some(input) = e.target_dyn_into::<HtmlInputElement>() {\n    input_value_handle.set(input.value());\n}","handlingStrategy":"type-guard","validationCode":"let on_dangerous_change = Callback::from(move |e: Event| {\n    let Some(target) = e.target() else {\n        return;\n    };\n    let _ = target;\n});","typeGuard":"use web_sys::{Event, HtmlInputElement};\n\nfn input_target(e: &Event) -> Option<HtmlInputElement> {\n    e.target_dyn_into::<HtmlInputElement>()\n}","tryCatchPattern":null,"preventionTips":["Use target_dyn_into::<HtmlInputElement>() instead of target().expect() + unchecked_into","In tests, dispatch change events from the input element so the target is populated","Centralize event-target extraction helpers instead of repeating expects per handler"],"tags":["yew","events","option-expect","wasm","panic"],"backgroundTag":"event-target-missing","analyzedSha":"0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3","analyzedAt":"2026-08-22T21:16:31.212Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}