Devolutions/UniGetUI · warning · TimeoutException

Task _getInstalledPackages for manager {Manager.Name} did no

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'.

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)

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.