Devolutions/UniGetUI · warning · TimeoutException

Task _getInstalledPackages for manager

Error message

Task _getInstalledPackages for manager {Manager.Name} did not finish after {PackageListingTaskTimeout} seconds, aborting.  You may disable timeouts from UniGetUI Advanced Settings

What it means

BaseSourceHelper._getSources runs each package manager's GetSources_UnSafe on a background Task under a hard 60-second ceiling (PackageListingTaskTimeout = 60). When the underlying CLI (e.g. `winget source list`, `scoop bucket list`, `choco source`) does not return in time, UniGetUI finalizes the 'dangerous task' and throws TimeoutException. The whole body is wrapped in try/catch that logs the error and returns an empty source list, so the visible symptom is a manager reporting no sources rather than a propagated throw. NOTE: the message text is a copy-paste bug — it says '_getInstalledPackages' but the method is '_getSources'.

Solutions

  1. Enable the UniGetUI Advanced Setting 'Disable timeouts on package listing tasks' (Settings.K.DisableTimeoutOnPackageListingTasks) so the wait becomes unbounded.
  2. Run the manager CLI directly and time it outside UniGetUI (`winget source list`, `scoop bucket list`, `choco source -r`) to confirm it is the slow step.
  3. Check proxy configuration, VPN/captive-portal state, and any pending UAC/gsudo prompt that the source-listing subprocess may be blocked on.
  4. Inspect UniGetUI logs (Logger.Error 'Error finding sources for manager <Name>') for the TimeoutException and the copy-paste text '_getInstalledPackages' to confirm it is this code path.
  5. Fix the message text in BaseSourceHelper.cs:96 from '_getInstalledPackages' to '_getSources' so diagnostics identify the correct task.

Example fix

// before (BaseSourceHelper.cs:95-99)
throw new TimeoutException(
    $"Task _getInstalledPackages for manager {Manager.Name} did not finish after "
        + $"{PackageListingTaskTimeout} seconds, aborting.  You may disable "
        + $"timeouts from UniGetUI Advanced Settings"
);

// after
throw new TimeoutException(
    $"Task _getSources for manager {Manager.Name} did not finish after "
        + $"{PackageListingTaskTimeout} seconds, aborting.  You may disable "
        + $"timeouts from UniGetUI Advanced Settings"
);
Defensive patterns

Strategy: fallback

Validate before calling

// Before calling GetSources(), confirm the manager is usable so the 60s
// timeout is not wasted on a disabled or network-bound manager.
if (!manager.IsReady())
    return Array.Empty<IManagerSource>();

if (!Settings.Get(Settings.K.DisableTimeoutOnPackageListingTasks)
     && !await NetworkIsAvailableAsync())
{
    Logger.Warn($"Skipping source listing for {manager.Name}: no network");
    return Array.Empty<IManagerSource>();
}

Try / catch

// GetSources() already swallows the TimeoutException and returns [].
// Only the *_Unsafe/protected path can throw, so guard there:
try
{
    IReadOnlyList<IManagerSource> sources = manager.SourceHelper.GetSources();
    if (sources.Count == 0)
        Logger.Warn($"{manager.Name} reported no sources (likely timed out)");
}
catch (TimeoutException ex)
{
    Logger.Error($"Source listing for {manager.Name} timed out: {ex.Message}");
}

Prevention

When it happens

Trigger: Calling BaseSourceHelper.GetSources() -> TaskRecycler.RunOrAttach(_getSources) -> _getSources -> Task.Run(GetSources_UnSafe), where GetSources_UnSafe spawns a manager CLI that has not exited within 60 s, AND Settings.K.DisableTimeoutOnPackageListingTasks is OFF. The throw only fires on that exact timeout path; with the setting ON, task.Wait() blocks indefinitely instead.

Common situations: Corporate proxy / captive portal blocking the package manager's source-list endpoint; an elevation (UAC/gsudo) prompt for adding/listing sources left unanswered; antivirus holding the spawned process; a slow first-run index rebuild; a flaky VPN dropping the connection mid-list. Often coincides with error 101 for the same manager.

Understand the failure class

Related errors


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

Appendix: source

Thrown at src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BaseSourceHelper.cs:95

        /// <summary>
        /// Loads the sources for the manager. This method SHOULD NOT handle exceptions
        /// </summary>
        protected abstract IReadOnlyList<IManagerSource> GetSources_UnSafe();

        public virtual IReadOnlyList<IManagerSource> GetSources() =>
            TaskRecycler<IReadOnlyList<IManagerSource>>.RunOrAttach(_getSources, 15);

        public virtual IReadOnlyList<IManagerSource> _getSources()
        {
            try
            {
                var task = Task.Run(GetSources_UnSafe);
                if (!task.Wait(TimeSpan.FromSeconds(PackageListingTaskTimeout)))
                {
                    if (!Settings.Get(Settings.K.DisableTimeoutOnPackageListingTasks))
                    {
                        CoreTools.FinalizeDangerousTask(task);
                        throw new TimeoutException(
                            $"Task _getInstalledPackages for manager {Manager.Name} did not finish after "
                                + $"{PackageListingTaskTimeout} seconds, aborting.  You may disable "
                                + $"timeouts from UniGetUI Advanced Settings"
                        );
                    }

                    task.Wait();
                }

                var sources = task.Result;
                Factory.Reset();

                foreach (IManagerSource source in sources)
                {
                    Factory.AddSource(source);
                }

                Logger.Debug($"Loaded {sources.Count} sources for manager {Manager.Name}");

View on GitHub (pinned to 9b1d7d0eab)