slint-ui/slint · error
Invalid type in public properties
Error message
Invalid type in public properties
What it means
In the C++ generator, public API is emitted only for property types that have a C++ representation. `p.ty.cpp_type()` returned None for a property included in the public API, so the generator panics. Only types mapped to C++ (int, float, bool, string, color, brushes, structs, models, etc.) may appear in a public component/global API.
Solutions
- Extend `Type::cpp_type()` in the compiler to map the missing type to a C++ type
- Remove the property from the public API or change its declared type to a C++-supported one
- Reproduce with the offending .slint file, identify the property type, and add a mapping or a compile-time rejection with a friendly diagnostic instead of an expect
Example fix
// before
let cpp_property_type = p.ty.cpp_type().expect("Invalid type in public properties");
// after
let cpp_property_type = p.ty.cpp_type().unwrap_or_else(||
panic!("property '{}' of type {:?} cannot be exposed to C++", prop_name, p.ty)); Defensive patterns
Strategy: validation
Validate before calling
fn is_cpp_expressible(ty: &Type) -> bool {
!matches!(ty, Type::Invalid | Type::Void) && ty.cpp_type().is_some()
}
// assert every public property passes is_cpp_expressible before codegen Type guard
fn assert_public_property_cpp_support(name: &str, ty: &Type) {
assert!(ty.cpp_type().is_some(), "public property '{name}' has no C++ type mapping ({ty:?})");
} Prevention
- Extend cpp_type() whenever a new builtin type is added
- Keep a test that generates C++ public API for every supported property type
- Reject non-mappable types at compile time with a diagnostic, not an expect
- Check the type before declaring a property public in .slint
When it happens
Trigger: A property or callback declared public whose Slint type has no `cpp_type()` mapping — e.g. an exotic internal type, a pure-layout type, or a newly added language type not yet mapped for C++ — is processed by `generate_public_api_for_properties` / the live-preview declaration path.
Common situations: Slint development: adding a new builtin type to the compiler and forgetting to extend `cpp_type()`; declaring public properties with types that are only valid internally; version drift between compiler types and the C++ generator.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Invalid type in public properties
- default value requested for unknown struct field
- Expression::ObjectAccess: Cannot find a key in an object
- model two-way bindings only exist on sub-components
- ShowPopupWindow is invoked on a sub-component
AI-assisted analysis of slint-ui/slint@3a7e700487 (2026-09-16).
Data as JSON: /api/errors/317fa5ce0468698f.
Report an issue: GitHub.
Appendix: source
Thrown at internal/compiler/generator/cpp.rs:3771
];
declarations.push((
Access::Public,
Declaration::Function(Function {
name: accessor_names::cpp_accessor_name(name, AccessorKind::Invoker),
signature: format!(
"({}) const -> {ret}",
param_types
.iter()
.enumerate()
.map(|(i, ty)| format!("{ty} arg_{i}"))
.join(", "),
),
statements: Some(call_code),
..Default::default()
}),
));
} else {
let cpp_property_type = p.ty.cpp_type().expect("Invalid type in public properties");
let prop_getter: Vec<String> = vec![
"slint::private_api::assert_main_thread();".into(),
"[[maybe_unused]] auto self = this;".into(),
format!("return {}.get();", access),
];
declarations.push((
Access::Public,
Declaration::Function(Function {
name: accessor_names::cpp_accessor_name(name, AccessorKind::Getter),
signature: format!("() const -> {cpp_property_type}"),
statements: Some(prop_getter),
..Default::default()
}),
));
if !p.read_only() {
let prop_setter: Vec<String> = vec![
"slint::private_api::assert_main_thread();".into(),View on GitHub (pinned to 3a7e700487)