WinGet Upgrade Workaround

When to use this

Some WinGet apps cannot be upgraded by winget upgrade, even though the newer version is listed in the Relution app store. The cause is almost always a broken upstream manifest on the WinGet side — the upgrade command then fails with no applicable upgrade, package not found, no applicable installer found, or a related error.

Microsoft’s own workaround is to install the app again with the --force flag. The script below automates that recovery for a single WinGet app and can be distributed to devices via a Relution store script or a script action.

This is a workaround. Only use it for apps where a normal upgrade is known to fail. Forcing an install replaces the existing package files and can mask other installation problems.

Script

The script can be created in Relution and run on a device via a script action. At the top of the script, set the $AppIdentifier variable to the exact WinGet identifier of the app you want to repair (for example Nextcloud.NextcloudDesktop).

$AppIdentifier = 'You need to set this'

# Silent flags required by Relution (Companion runs as SYSTEM, no UI)
$SilentFlags = @(
    '--silent',
    '--disable-interactivity',
    '--accept-package-agreements',
    '--accept-source-agreements'
)

# Resolve winget.exe for SYSTEM context (DesktopAppInstaller package)
$winget = Resolve-Path 'C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*\winget.exe' -ErrorAction SilentlyContinue |
    Select-Object -First 1 -ExpandProperty Path

if (-not $winget) {
    Write-Error 'winget.exe not found in System context.'
    exit 1
}

Write-Host "Using winget at: $winget"

# 1. Check if the app is installed
& $winget list --id $AppIdentifier --exact --accept-source-agreements --disable-interactivity | Out-Null
if ($LASTEXITCODE -ne 0) {
    Write-Host "$AppIdentifier is not installed - nothing to do."
    exit 0
}

# 2. Try the upgrade
& $winget upgrade --id $AppIdentifier --exact @SilentFlags
$code = $LASTEXITCODE

if ($code -eq 0) {
    Write-Host "Upgrade completed successfully."
    exit 0
}

Write-Warning "Upgrade failed with exit code $code."

# 3. Fallback for broken manifests / no applicable installer / package not found
$FallbackCodes = @(
    -1978335189,  # no applicable upgrade
    -1978335215,  # package not found
    -1978335192,  # no applicable installer found
    -1978335216   # manifest / installer failure observed in practice
)

if ($code -in $FallbackCodes) {
    Write-Warning "Retrying as 'install --force'..."
    & $winget install --id $AppIdentifier --exact --force @SilentFlags
    exit $LASTEXITCODE
}

exit $code

How it works

  1. The script resolves winget.exe inside C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_* — the installation used by the Windows Companion in System context.
  2. It calls winget list --id <AppIdentifier> --exact to check whether the app is already installed. If not, the script exits without doing anything.
  3. It calls winget upgrade --id <AppIdentifier> --exact with Relution’s mandatory silent flags. The flags are splatted with @SilentFlags so PowerShell passes each element as a separate argument — required for WinGet to parse them. If the upgrade succeeds, the script exits.
  4. If the upgrade exits with one of the recoverable WinGet error codes, the script retries as winget install --id <AppIdentifier> --exact --force with the same silent flags. The recoverable codes are:
    • -1978335189no applicable upgrade
    • -1978335215package not found
    • -1978335192no applicable installer found
    • -1978335216 — manifest / installer failure observed in practice
  5. Every other WinGet exit code is surfaced unchanged.