Devolutions/UniGetUI · error · InvalidOperationException

The maintenance command exited with code {process.ExitCode}.

Error message

The maintenance command exited with code {process.ExitCode}.

What it means

Thrown by RunWindowsProcessAsync after a spawned maintenance subprocess (PowerShell 5 running a WinGet repair, Scoop install/uninstall, or Scoop cleanup script) exits with a non-zero ExitCode. The maintenance pipeline shells out to external CLI tools and treats any non-zero return as a hard failure, wrapping the numeric code in an InvalidOperationException.

Source

Thrown at src/UniGetUI.Interface.IpcApi/IpcManagerMaintenanceApi.cs:336

        bool runAsAdmin = false
    )
    {
        using Process process = new()
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = fileName,
                Arguments = arguments,
                UseShellExecute = runAsAdmin,
                Verb = runAsAdmin ? "runas" : string.Empty,
                CreateNoWindow = !runAsAdmin,
            },
        };
        process.Start();
        await process.WaitForExitAsync();
        if (process.ExitCode != 0)
        {
            throw new InvalidOperationException(
                $"The maintenance command exited with code {process.ExitCode}."
            );
        }
    }

    private static void EnsureConfirmed(IpcManagerMaintenanceRequest request, string action)
    {
        if (!request.Confirm)
        {
            throw new InvalidOperationException(
                $"The manager action \"{action}\" requires confirm=true."
            );
        }
    }

    private static void EnsureManager(IPackageManager manager, string expectedName)
    {
        if (!manager.Name.Equals(expectedName, StringComparison.OrdinalIgnoreCase))

View on GitHub (pinned to 9b1d7d0eab)

Solutions

  1. Check the exit code in the exception message — a UAC denial typically returns code 1223, while execution-policy issues return 1.
  2. For Scoop actions, first call GetMaintenanceInfo to confirm Ready=true and ExecutablePath is populated.
  3. Run the same PowerShell command manually in an elevated shell to see the real error output before the process exits.
  4. For repair-winget, verify App Installer (Microsoft.DesktopAppInstaller) is installed and not corrupt before retrying.

Example fix

// before — calling cleanup on an unready Scoop manager
await IpcManagerMaintenanceApi.RunActionAsync(new IpcManagerMaintenanceRequest {
    ManagerName = "Scoop", Action = "cleanup-scoop", Confirm = true
});
// after — verify readiness first
var info = IpcManagerMaintenanceApi.GetMaintenanceInfo("Scoop");
if (!info.Ready)
    throw new InvalidOperationException("Scoop is not ready; install it first.");
await IpcManagerMaintenanceApi.RunActionAsync(new IpcManagerMaintenanceRequest {
    ManagerName = "Scoop", Action = "cleanup-scoop", Confirm = true
});
Defensive patterns

Strategy: try-catch

Validate before calling

var info = IpcManagerMaintenanceApi.GetMaintenanceInfo(request.ManagerName);
if (!info.Ready && request.Action is "cleanup-scoop")
    throw new InvalidOperationException("Manager is not ready for this action.");

Try / catch

try
{
    await IpcManagerMaintenanceApi.RunActionAsync(request);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("exited with code"))
{
    logger.LogError("Maintenance command failed: {Message}", ex.Message);
    // Surface the exit code to the user for manual diagnosis
}

Prevention

When it happens

Trigger: Calling IpcManagerMaintenanceApi.RunActionAsync with action 'repair-winget', 'install-scoop', 'uninstall-scoop', or 'cleanup-scoop' where the underlying PowerShell process returns non-zero. For cleanup-scoop specifically, manager.Status.ExecutablePath must be set first or a different error fires; if it is set but scoop cleanup exits non-zero, this error fires.

Common situations: WinGet repair fails because App Installer is corrupt or PowerShell execution policy blocks the inline script. Scoop install fails due to network issues or restricted environment. Scoop cleanup fails when a bucket is stale or the global scope requires admin elevation that was denied by UAC. The runAsAdmin=true path uses 'runas' Verb, so a UAC prompt declined by the user would cause the process to exit non-zero.

Related errors


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