slint-ui/slint · error · RuntimeError

Callback '{name}' in global '{global_name}' cannot be used w

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

For @slint.callback-decorated async functions bound to a global, Slint requires the callback to be declared with no return type (void). Async handlers return a coroutine to Slint's synchronous callback invocation, so a return value cannot be delivered; if global_callback_returns_void() returns False (callback exists but is declared `-> something`), instantiation raises this RuntimeError.

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 a9ea814a58)

Solutions

  1. Declare the callback without a return type in the global: `callback fetch(name: string);` and reload the .slint.
  2. Deliver results asynchronously by setting a property (or calling a Slint function) from the coroutine after the await completes.
  3. If Slint must consume a return value synchronously, keep the callback sync (no `async def`).

Example fix

// before (main.slint)
export global Net { callback query(string) -> string; }

@slint.callback
async def query(self, q): ...  # RuntimeError at instantiation

// after
export global Net {
    callback query(string);          // fire-and-forget
    out property <string> result;
}

@slint.callback
async def query(self, q):
    self.Net.result = await do_query(q)  # push result via property
Defensive patterns

Strategy: validation

Validate before calling

# Lint: async @slint.callback handlers on globals must map to `callback name(...);` with no `->`
import re
src = open("app.slint").read()
for m in re.finditer(r"callback\s+(\w+)\s*\([^)]*\)\s*->", src):
    if m.group(1) in async_global_callbacks:
        raise SystemExit(f"global callback '{m.group(1)}' must be void for an async handler")

Try / catch

try:
    app = App()
except RuntimeError as e:
    if "doesn't return void" in str(e):
        raise SystemExit("Declare the async callback without a return type and push results via properties") from e
    raise

Prevention

When it happens

Trigger: `callback fetch(name: string) -> string;` declared inside a global in .slint, combined with `@slint.callback` + `async def fetch(self, name)` in the Python subclass of the component. The error is raised when the component instance is constructed.

Common situations: Porting a synchronous callback (that returns a value) to async by just adding `async`; wanting to await I/O inside the handler while keeping the old `-> T` declaration; forgetting that async callbacks in Slint are fire-and-forget.

Related errors


AI-assisted analysis of slint-ui/slint@a9ea814a58 (2026-08-16). Data as JSON: /api/errors/309837bf4ab06779. Report an issue: GitHub.