slint-ui/slint · error
default value requested for unknown struct field
Error message
default value requested for unknown struct field
What it means
`default_value_for_field` looks up a field's default: first in `field_defaults`, else via the field's type in `fields`. The panic means the requested field name exists in neither map — an unknown struct field was queried.
Solutions
- Check `fields.contains_key(name)` (or use `.get()` returning Option) before requesting the default
- Ensure earlier passes reject unknown struct fields so this is never reached with a bad name
- If triggered by valid user code, reduce the .slint file and file a compiler bug
Example fix
// before
self.fields.get(name).expect("default value requested for unknown struct field")
// after
match self.fields.get(name) {
Some(ty) => Expression::default_value_for_type(ty),
None => return Expression::Invalid, // or propagate an error
} Defensive patterns
Strategy: type-guard
Validate before calling
if !struct_ty.fields.contains_key(field_name) {
return Err(format!("unknown struct field: {field_name}"));
} Type guard
fn known_field(s: &Struct, name: &str) -> bool { s.fields.contains_key(name) } Try / catch
// unreachable in normal operation; wrap pass invocation to catch panics if running untrusted input std::panic::catch_unwind(|| default_value_for_field(name))
Prevention
- Validate field names against `fields` before requesting defaults
- Keep early passes rejecting unknown struct fields
When it happens
Trigger: Calling `default_value_for_field` with a name not present in the struct's `fields` — e.g. a two-way binding or expression referencing a struct property with a typo'd/renamed field before name-resolution rejects it, or a pass assuming a field exists after a type erasure.
Common situations: Compiler developers adding passes that fabricate field accesses without checking `Type::Struct.fields`; users indirectly trigger it via struct property initializers with extra/misspelled fields if upstream validation changed.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- a setter belongs to a field
- an identifier
- element without a size
- invalid parent reference
- large glyph x coordinate
AI-assisted analysis of slint-ui/slint@3a7e700487 (2026-09-16).
Data as JSON: /api/errors/2b4d0202e32be45c.
Report an issue: GitHub.
Appendix: source
Thrown at internal/compiler/langtype.rs:1190
StructName::User { rust_attributes, .. } => rust_attributes,
_ => &[],
}
}
/// The field names in declaration order for a user-declared struct.
pub fn field_order(&self) -> &[SmolStr] {
match &self.name {
StructName::User { field_order, .. } => field_order,
_ => &[],
}
}
/// The default value for the given field: the user-declared default if there is one,
/// otherwise the default value for the field's type.
pub fn default_value_for_field(&self, name: &SmolStr) -> Expression {
self.field_defaults.get(name).map(ConstantExpression::to_expression).unwrap_or_else(|| {
Expression::default_value_for_type(
self.fields.get(name).expect("default value requested for unknown struct field"),
)
})
}
}
/// A constant expression, used for the default values of struct fields
/// (see [`Struct::field_defaults`]).
///
/// This is deliberately neither [`Expression`] nor an llr expression:
/// unlike those, it cannot reference any properties, elements, or syntax nodes,
/// so a [`Struct`] carrying one can safely outlive the object tree.
/// The variants are the subset that every consumer can materialize.
/// Keep the matches over this type exhaustive,
/// so that adding a variant is a compile error in each consumer:
/// the conversion to an expression tree ([`Self::to_expression`]),
/// the lowering for the code generators (`lower_constant_expression` in the llr module),
/// and the interpreter's evaluator (`eval_constant_expression` there).
#[derive(Debug, Clone)]View on GitHub (pinned to 3a7e700487)