{"record":{"id":"70ec7f4c31c0e728","repo":"slint-ui/slint","slug":"binding-was-of-the-wrong-type","errorCode":null,"errorMessage":"binding was of the wrong type","messagePattern":"binding was of the wrong type","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/core/rtti.rs","lineNumber":260,"sourceCode":"    ) -> Result<(), ()> {\n        if animation.is_some() {\n            Err(())\n        } else {\n            self.apply_pin(item).set(value.try_into().map_err(|_| ())?);\n            Ok(())\n        }\n    }\n    fn set_binding(\n        &self,\n        item: Pin<&Item>,\n        binding: Box<dyn Fn() -> Value>,\n        animation: AnimatedBindingKind,\n    ) -> Result<(), ()> {\n        if !matches!(animation, AnimatedBindingKind::NotAnimated) {\n            Err(())\n        } else {\n            self.apply_pin(item).set_binding(move || {\n                binding().try_into().map_err(|_| ()).expect(\"binding was of the wrong type\")\n            });\n            Ok(())\n        }\n    }\n    fn offset(&self) -> usize {\n        self.get_byte_offset()\n    }\n\n    #[cfg(slint_debug_property)]\n    fn set_debug_name(&self, item: Pin<&Item>, name: alloc::string::String) {\n        self.apply_pin(item).debug_name.replace(name);\n    }\n\n    #[allow(unsafe_code)]\n    unsafe fn link_two_ways(&self, item: Pin<&Item>, property2: *const c_void) {\n        let p1 = self.apply_pin(item);\n        // Safety: that's the invariant of this function\n        let p2 = unsafe { Pin::new_unchecked((property2 as *const Property<T>).as_ref().unwrap()) };","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/slint-ui/slint/blob/3a7e700487dc74d404cad0726378053ab763d4e0/internal/core/rtti.rs#L242-L278","documentation":"In the non-animated `Rtti::set_binding` implementation, the user-supplied binding is evaluated and its `Value` result is converted with `try_into()` to the property's native type; a failed conversion is mapped to `Err(())` and then immediately unwrapped with `.expect(\"binding was of the wrong type\")`. This panics when a binding set through the RTTI/dynamic-property API produces a Value that cannot be converted into the property element type T.","triggerScenarios":"Calling `set_binding` on a dynamically-accessed property (e.g. via the interpreter / `DynamicType` RTTI path) where the closure returns a `Value` of a different type than the property declared (e.g. assigning a string Value to an int property, or a length to a color).","commonSituations":"Interpreter/Node/Python/C++ FFI code setting properties with values of the wrong Slint type; property type changed in .slint markup without updating the binding code.","solutions":["Make the binding closure return a `Value` whose type matches the property's declared type (use the property's default value as a template)","Check the property's type via RTTI (`PropertyRtti::type_()`) before binding and construct the matching Value variant","If types can vary at runtime, perform an explicit, graceful conversion inside the closure instead of relying on try_into"],"exampleFix":"// before\nhandle.set_binding(prop, || Value::String(\"42\".into()), AnimatedBindingKind::NotAnimated);\n// after\nhandle.set_binding(prop, || Value::Number(42.0), AnimatedBindingKind::NotAnimated);","handlingStrategy":"type-guard","validationCode":"// check the property's declared type before binding\nlet prop_type = prop_rtti.ty();\nlet value_type = std::mem::discriminant(&value);\nassert_eq!(value_type_matches(prop_type, &value), true);","typeGuard":"fn value_matches(prop_ty: ValueType, v: &Value) -> bool {\n    matches!((prop_ty, v),\n        (ValueType::Number, Value::Number) |\n        (ValueType::String, Value::String) |\n        (ValueType::Bool, Value::Bool) | /* ... */ )\n}","tryCatchPattern":"// expect() panics, so use catch_unwind only as a last resort\nlet result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| handle.set_binding(prop, binding, kind)));","preventionTips":["Query PropertyRtti::type_() and construct the matching Value variant","Derive binding values from the property's default value","Keep FFI/interpreter property setters in sync with .slint declarations","Add unit tests that set every dynamic property once"],"tags":["rust","panic","type-mismatch","rtti","binding"],"backgroundTag":"type-mismatch","analyzedSha":"3a7e700487dc74d404cad0726378053ab763d4e0","analyzedAt":"2026-09-16T01:37:20.251Z","contentChangedAt":"2026-09-16T01:37:20.251Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}