slint-ui/slint · error

Cannot invoke callback

Error message

Cannot invoke callback {global_name}::{name}: {e}

What it means

LiveComponent::invoke_global panics when the interpreter fails to invoke a callback declared on a global singleton. The method returns Value directly, so any interpreter error (unknown global/callback, wrong argument count/types) is surfaced as a panic instead of a Result.

Solutions

  1. Match the args slice length and Value types to the callback's declared signature
  2. Verify the callback is declared on the exported global (not the root element)
  3. After a .slint hot-reload, re-look-up callback names before invoking

Example fix

// before
live.invoke_global("Logic", "compute", &[]); // callback expects one int arg
// after
live.invoke_global("Logic", "compute", &[Value::Number(42.0)]);
Defensive patterns

Strategy: validation

Validate before calling

fn callback_arity(declared: usize, args: &[Value]) -> bool { declared == args.len() }
// compare against the callback's declared parameter count from the ComponentDefinition before invoking

Try / catch

// panic! is not catchable; check name and argument count before invoke
if args.len() == declared_param_count {
    live.invoke_global("Logic", "compute", args);
}

Prevention

When it happens

Trigger: invoke_global(global_name, name, args) where the global or callback name does not resolve, or the args slice does not match the callback's declared parameter types/arity.

Common situations: Invoking a callback with missing or extra arguments; calling a component-root callback via invoke_global instead of set_callback-wrapped invocation; stale names after live-reload.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at internal/live-preview/live_component.rs:231

    pub fn set_global_property(&self, global_name: &str, name: &str, value: Value) {
        self.properties.borrow_mut().insert(format!("{global_name}.{name}"), value.clone());
        self.instance()
            .set_global_property(global_name, name, value)
            .unwrap_or_else(|e| panic!("Cannot set property {global_name}::{name}: {e}"))
    }

    /// forward to get_global_property
    pub fn get_global_property(&self, global_name: &str, name: &str) -> Value {
        self.instance()
            .get_global_property(global_name, name)
            .unwrap_or_else(|e| panic!("Cannot get property {global_name}::{name}: {e}"))
    }

    /// Forward to invoke_global
    pub fn invoke_global(&self, global_name: &str, name: &str, args: &[Value]) -> Value {
        self.instance()
            .invoke_global(global_name, name, args)
            .unwrap_or_else(|e| panic!("Cannot invoke callback {global_name}::{name}: {e}"))
    }

    /// Forward to set_global_callback
    pub fn set_global_callback(
        &self,
        global_name: &str,
        name: &str,
        callback: Rc<dyn Fn(&[Value]) -> Value + 'static>,
    ) {
        self.callbacks.borrow_mut().insert(format!("{global_name}.{name}"), callback.clone());
        self.instance()
            .set_global_callback(global_name, name, move |args| callback(args))
            .unwrap_or_else(|e| panic!("Cannot set callback {global_name}::{name}: {e}"));
    }
}

enum WatcherState {
    Starting,

View on GitHub (pinned to 3a7e700487)