{"record":{"id":"6dafc5a2301b2277","repo":"yewstack/yew","slug":"could-not-set-property","errorCode":null,"errorMessage":"could not set property","messagePattern":"could not set property","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/yew/src/dom_bundle/btag/attributes.rs","lineNumber":179,"sourceCode":"            }\n        }\n\n        // Remove missing\n        for (k, old_value) in old.iter() {\n            if !new.contains_key(k) {\n                Self::remove(el, k, old_value);\n            }\n        }\n    }\n\n    fn set(el: &Element, key: &str, value: &AttributeOrProperty) {\n        match value {\n            AttributeOrProperty::Attribute(value) => el\n                .set_attribute(intern(key), value)\n                .expect(\"invalid attribute key\"),\n            AttributeOrProperty::Property(value) => {\n                let key = JsValue::from_str(key);\n                js_sys::Reflect::set(el.as_ref(), &key, value).expect(\"could not set property\");\n            }\n        }\n    }\n\n    /// Applies a value during hydration.\n    ///\n    /// Hydration assumes the DOM already matches the server-rendered HTML, so\n    /// attributes are left untouched: re-writing them would needlessly trigger\n    /// side effects. In debug builds we only assert that the existing attribute\n    /// matches the expected value. Properties are not reflected in the HTML, so\n    /// they are always set.\n    #[cfg(feature = \"hydration\")]\n    fn hydrate_set(el: &Element, key: &str, value: &AttributeOrProperty) {\n        match value {\n            AttributeOrProperty::Attribute(value) => {\n                debug_assert_eq!(\n                    el.get_attribute(key).as_deref(),\n                    Some(value.as_ref()),","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/yewstack/yew/blob/0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3/packages/yew/src/dom_bundle/btag/attributes.rs#L161-L197","documentation":"When a value is applied as a DOM property (packages/yew/src/dom_bundle/btag/attributes.rs:179), Yew uses js_sys::Reflect::set and unwraps with .expect(\"could not set property\"). Reflect::set throws a TypeError when the target property is an accessor without a setter (getter-only like dataset, classList, isContentEditable) or non-writable/non-configurable, or when the property's own setter throws for the supplied value (e.g. an invalid value passed to a validating setter).","triggerScenarios":"Setting a getter-only DOM property (dataset, classList, isContentEditable) through Yew property syntax; assigning a value the browser setter rejects, such as a malformed value to a property whose setter validates; setting a property on a frozen or non-configurable target element.","commonSituations":"Trying to bind classList/dataset as if they were settable properties instead of using classes!/attribute syntax; passing wrong-typed values to typed setters; plugins or tests freezing DOM objects before Yew patches attributes.","solutions":["Use the proper Yew API for the target: classes for class lists, attributes or listeners syntax for dataset-style data instead of property assignment","Check the property is writable (has a setter) before assigning: js_sys::Reflect::get_own_property_descriptor or a quick manual check against a known getter-only list","Ensure the value type matches what the DOM setter expects (bool vs string for checked/disabled style properties)"],"exampleFix":"// before\nhtml! { <div dataset={some_map} /> }  // dataset is getter-only\n\n// after\nhtml! { <div data-role={\"panel\"} /> }  // set as attributes instead","handlingStrategy":"validation","validationCode":"// allowlist writable properties before assigning them dynamically\nconst WRITABLE_PROPS: &[&str] = &[\"value\", \"checked\", \"href\", \"selected\", \"disabled\", \"innerHTML\"];\nfn is_writable_prop(name: &str) -> bool { WRITABLE_PROPS.contains(&name) }\n\nif is_writable_prop(&key) { /* set property */ } else { /* set as attribute instead */ }","typeGuard":"fn is_getter_only_dom_prop(name: &str) -> bool { matches!(name, \"dataset\" | \"classList\" | \"isContentEditable\" | \"style\" ) }","tryCatchPattern":null,"preventionTips":["Use classes! for class lists and attribute syntax for data-* instead of property assignment","Check MDN that a property has a setter before binding it in Yew property syntax","Match value types to what the DOM setter expects"],"tags":["rust","wasm","yew","dom","properties","runtime-panic"],"backgroundTag":"dom-property-set-failed","analyzedSha":"0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3","analyzedAt":"2026-08-22T21:16:31.212Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}