slint-ui/slint · error · RuntimeError

Callback ' ' in global ' ' cannot be used with a callback…

Error message

Callback '${name}' in global '${global_name}' cannot be used with a callback decorator for an async function, as it doesn't return void

What it means

Raised by the @slint.callback decorator when decorating an async function that targets a global callback declared in the .slint file whose return type is not void. Async Python callbacks can only be wired to Slint callbacks that return nothing, because the runtime fires the callback without awaiting a result value to hand back to the Slint side.

Solutions

  1. Change the Slint global callback declaration to return nothing: remove `-> type` from `callback name(...) -> type`.
  2. Make the Python handler a regular (non-async) function and return the value synchronously if the Slint side needs a result.
  3. Keep the handler async but communicate the result via a property or a separate void callback instead of the return value.

Example fix

# before (.slint)
export global Logic { callback compute(int) -> int; }

# Python (async) -> RuntimeError
@slint.callback("compute")
async def compute(x): return x * 2

# after: either make it void in .slint, or use a sync handler
@slint.callback("compute")
def compute(x):
    return x * 2
Defensive patterns

Strategy: validation

Validate before calling

def check_void_callback(comp, name):
    if comp.callback_returns_void(name) is False:
        raise TypeError(f"callback '{name}' returns a value; async handler not allowed")

Type guard

def is_async_handler(fn):
    return asyncio.iscoroutinefunction(fn)

Try / catch

try:
    component.compute = handler
except (RuntimeError, AttributeError) as e:
    logging.error("callback binding failed: %s", e)

Prevention

When it happens

Trigger: Applying slint.callback() to an `async def` handler whose `name` refers to a callback in a global (exported global component) that was declared with a non-void return type, e.g. `callback foo(int) -> string`.

Common situations: Declaring a global callback with a return type in .slint (for the sync variant) and later switching the Python handler to async without changing the declaration; mixing async/await refactors into existing global callback handlers.

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


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

Appendix: source

Thrown at api/python/slint/slint/__init__.py:182

        self.__instance__ = compdef.create()
        for name, value in self.__class__.__dict__.items():
            if hasattr(value, "slint.callback"):
                callback_info = getattr(value, "slint.callback")
                name = callback_info["name"]

                is_async = getattr(value, "slint.async", False)
                if is_async:
                    if "global_name" in callback_info:
                        global_name = callback_info["global_name"]
                        is_void = compdef.global_callback_returns_void(
                            global_name, name
                        )
                        if is_void is None:
                            raise AttributeError(
                                f"Callback '{name}' in global '{global_name}' cannot be used with a callback decorator for an async function, as it is not declared in Slint component"
                            )
                        if not is_void:
                            raise RuntimeError(
                                f"Callback '{name}' in global '{global_name}' cannot be used with a callback decorator for an async function, as it doesn't return void"
                            )
                    else:
                        is_void = compdef.callback_returns_void(name)
                        if is_void is None:
                            raise AttributeError(
                                f"Callback '{name}' cannot be used with a callback decorator for an async function, as it is not declared in Slint component"
                            )
                        if not is_void:
                            raise RuntimeError(
                                f"Callback '{name}' cannot be used with a callback decorator for an async function, as it doesn't return void"
                            )

                def mk_callback(
                    self: Any, callback: typing.Callable[..., Any]
                ) -> typing.Callable[..., Any]:
                    def invoke(*args: Any, **kwargs: Any) -> Any:
                        return callback(self, *args, **kwargs)

View on GitHub (pinned to bb937076de)