Devolutions/UniGetUI · error · InvalidOperationException

The current UniGetUI session cannot update all packages.

Error message

The current UniGetUI session cannot update all packages.

What it means

Thrown by the IPC server's POST v3 update-all endpoint when the OnUpgradeAll event has no subscriber. The host process (typically the main UniGetUI GUI) registers the handler; if it is null the endpoint cannot perform the bulk upgrade and refuses with InvalidOperationException. HandleCommandAsync catches it and returns HTTP 400 with this message as the body.

Source

Thrown at src/UniGetUI.Interface.IpcApi/IpcServer.cs:1595

                    IpcJson.Options
                );
            }
            catch (InvalidOperationException ex)
            {
                context.Response.StatusCode = 400;
                await context.Response.WriteAsync(ex.Message);
            }
        }

        private async Task V3_UpdateAllPackages(HttpContext context)
        {
            await HandleCommandAsync(
                context,
                () =>
                {
                    if (OnUpgradeAll is null)
                    {
                        throw new InvalidOperationException(
                            "The current UniGetUI session cannot update all packages."
                        );
                    }

                    OnUpgradeAll.Invoke(null, EventArgs.Empty);
                    return IpcCommandResult.Success("update-all");
                }
            );
        }

        private async Task V3_UpdateAllPackagesForManager(HttpContext context)
        {
            await HandleCommandAsync(
                context,
                () =>
                {
                    if (OnUpgradeAllForManager is null)
                    {

View on GitHub (pinned to 9b1d7d0eab)

Solutions

  1. Ensure the host subscribes to IpcServer.OnUpgradeAll before starting the listener (the normal UniGetUI app does this in startup wiring).
  2. If integrating IpcServer standalone, attach a handler: server.OnUpgradeAll += (_, _) => { /* trigger upgrade-all */ };
  3. As an API caller, treat HTTP 400 with this body as 'feature unavailable in this session' and surface a user-facing message rather than retrying.

Example fix

// before: endpoint called but OnUpgradeAll never subscribed -> HTTP 400
// after: wire the event before MapRoutes/RunAsync
ipcServer.OnUpgradeAll += (_, _) => PMManager.UpgradeAllPackages();
await ipcServer.StartAsync(cancellationToken);
Defensive patterns

Strategy: validation

Validate before calling

// Before calling the update-all endpoint, confirm the host wired the handler.
// (IPC clients cannot inspect OnUpgradeAll directly; treat HTTP 400 with this body as 'unavailable'.)
if (response.StatusCode == HttpStatusCode.BadRequest &&
    await response.Content.ReadAsStringAsync() == "The current UniGetUI session cannot update all packages.")
{
    // feature unavailable in this session
}

Try / catch

// Host side: never null if you wire the event. No try-catch needed.
// If wiring conditionally, guard:
if (ipcServer.OnUpgradeAll is not null) { /* safe to expose endpoint */ }

Prevention

When it happens

Trigger: Calling the IPC v3 update-all route (V3_UpdateAllPackages) while OnUpgradeAll is null — i.e. no GUI/session wired the upgrade-all callback before the request arrived.

Common situations: Headless/automation clients hitting the IPC API before the main app fully started; a forked/embedded use of IpcServer that never subscribed to OnUpgradeAll; calling the endpoint during shutdown after the handler was detached.

Related errors


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