Devolutions/UniGetUI · warning · InvalidOperationException

The current UniGetUI session is running headless and has no

Error message

The current UniGetUI session is running headless and has no window to show.

What it means

HeadlessIpcHost.CreateIpcServer wires a ShowAppHandler that unconditionally throws InvalidOperationException. The headless daemon has no GUI window, so any IPC command asking to show or activate the application window is impossible. The handler is set deliberately (not null) so that a show-window request fails loudly instead of silently no-op'ing. Callers should check AppInfoProvider().CanShowWindow (false in headless) before attempting to show.

Source

Thrown at src/UniGetUI.Interface.IpcApi/HeadlessIpcHost.cs:81

    private static IpcServer CreateIpcServer(Action requestShutdown)
    {
        var backgroundApi = new IpcServer
        {
            SessionKind = IpcTransportOptions.HeadlessSessionKind,
        };
        backgroundApi.AppInfoProvider = () =>
            new IpcAppInfo
            {
                Headless = true,
                WindowAvailable = false,
                WindowVisible = false,
                CanShowWindow = false,
                CanNavigate = false,
                CanQuit = true,
                SupportedPages = IpcAppPages.SupportedPages,
            };
        backgroundApi.ShowAppHandler = () =>
            throw new InvalidOperationException(
                "The current UniGetUI session is running headless and has no window to show."
            );
        backgroundApi.NavigateAppHandler = _ =>
            throw new InvalidOperationException(
                "The current UniGetUI session is running headless and cannot navigate UI pages."
            );
        backgroundApi.QuitAppHandler = () =>
        {
            _ = Task.Run(async () =>
            {
                await Task.Delay(150);
                requestShutdown();
            });
            return IpcCommandResult.Success("quit-app");
        };

        return backgroundApi;
    }

View on GitHub (pinned to 9b1d7d0eab)

Solutions

  1. Before sending a show-window command, query AppInfoProvider and check CanShowWindow == true.
  2. Launch the full Avalonia GUI process instead of (or in addition to) the headless daemon if window display is needed.
  3. Handle the InvalidOperationException in the IPC client and fall back to launching the GUI.

Example fix

// before: unconditionally requesting the daemon to show its window
await ipc.ShowAppAsync();
// after: check capability first
var info = await ipc.GetAppInfoAsync();
if (info.CanShowWindow)
    await ipc.ShowAppAsync();
else
    CoreTools.Launch(guiExecutablePath);
Defensive patterns

Strategy: validation

Validate before calling

var info = await ipc.GetAppInfoAsync();
if (info.CanShowWindow)
    await ipc.ShowAppAsync();

Type guard

static bool CanShowWindow(IpcAppInfo info) => info is { Headless: false, CanShowWindow: true };

Try / catch

try { await ipc.ShowAppAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("headless"))
{ Logger.Warn("Cannot show window in headless session."); }

Prevention

When it happens

Trigger: An IPC client connected to the headless daemon sends a 'show-app' or 'activate-window' command. The IpcServer invokes backgroundApi.ShowAppHandler, which throws. This occurs when a client assumes a GUI session is available but is actually talking to the background-only daemon.

Common situations: A tray-icon launcher or CLI bridge sends show-window commands to the background daemon instance. A client connects to the wrong IPC session (headless instead of GUI). A script assumes the running process is the full Avalonia app when it is actually the headless daemon.

Related errors


AI-assisted analysis of Devolutions/UniGetUI@9b1d7d0eab (2026-08-13). Data as JSON: /api/errors/85efaff495811402. Report an issue: GitHub.