slint-ui/slint · error

unsupported builtin struct field default

Error message

unsupported builtin struct field default `{tokens}`

What it means

The Python binding's `declared_default_value` converts a builtin struct field's declared default (a token string from .slint markup) into a Python value. It accepts booleans and numbers; any other non-numeric token panics with this message. It means a default value in a builtin struct definition is of a type the Python codegen cannot express.

Solutions

  1. Change the field's declared default in the builtin definition to a plain boolean or numeric literal
  2. Add a parsing branch in declared_default_value for the new default type (e.g. strip unit or map colors) before the f64 fallback
  3. If the default is inherently non-numeric, skip Python default generation for that field instead of panicking

Example fix

// before (builtins):
property <length> offset: 4px;
// after
property <length> offset: 4.0; // or handle unit parsing in declared_default_value
Defensive patterns

Strategy: validation

Validate before calling

def ensure_supported_default(value: str) -> None:
    if value in ("true", "false"):
        return
    try:
        float(value)
    except ValueError:
        raise ValueError(f"default {value!r} must be bool or numeric for Python codegen")

Prevention

When it happens

Trigger: A builtin struct field in the Slint compiler's builtins declares a textual default value that is neither `true`/`false` nor parses as f64 — e.g. a color, string, length-with-unit ("4px"), or enum default.

Common situations: Developers extending builtin structs in the compiler (builtins.slint) adding fields with defaults of unsupported types (lengths, strings, colors) while testing the Python backend; unit-suffixed literals like `4px` fail f64 parsing.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16). Data as JSON: /api/errors/582f3d3467938239. Report an issue: GitHub.

Appendix: source

Thrown at api/python/slint/language.rs:50

/// so `register_structs` must run after `register_enums`.
fn declared_default_value<'py>(
    py: Python<'py>,
    m: &Bound<'py, PyModule>,
    tokens: &str,
    rust_ty: &str,
) -> PyResult<Bound<'py, PyAny>> {
    let text: String =
        tokens.chars().filter(|c| !c.is_whitespace() && *c != '(' && *c != ')').collect();
    if let Some((enum_name, variant)) = text.split_once("::") {
        let member = to_kebab_case(variant.trim_start_matches("r#")).replace('-', "_");
        return language_submodule(py, m)?.getattr(enum_name)?.getattr(member.as_str());
    }
    if let Ok(b) = text.parse::<bool>() {
        return b.into_bound_py_any(py);
    }
    let value = text
        .parse::<f64>()
        .unwrap_or_else(|_| panic!("unsupported builtin struct field default `{tokens}`"));
    if rust_ty == "i32" {
        (value as i32).into_bound_py_any(py)
    } else {
        value.into_bound_py_any(py)
    }
}

/// Returns the `slint.language` submodule, creating and registering it on the parent
/// module + `sys.modules` on first call so `from slint.language import …` works.
fn language_submodule<'py>(
    py: Python<'py>,
    m: &Bound<'py, PyModule>,
) -> PyResult<Bound<'py, PyModule>> {
    match m.getattr("language") {
        Ok(existing) => Ok(existing.cast_into::<PyModule>()?),
        Err(_) => {
            let sub = PyModule::new(py, "slint.language")?;
            m.add("language", &sub)?;

View on GitHub (pinned to bb937076de)