BCUninstaller/Bulk-Crap-Uninstaller · error · IOException
Uninstaller timed out
Error message
Uninstaller timed out
What it means
In the uninstaller-watch loop, BulkUninstallEntry polls the spawned uninstaller processes; if TestUninstallerForStalls returns true for more than 30 consecutive iterations (idleCounter > 30), it kills them and throws IOException using Localisation.UninstallError_UninstallerTimedOut. This is the stall-detection safeguard that prevents a hung uninstaller from blocking a bulk run indefinitely.
Source
Thrown at source/UninstallTools/Uninstaller/BulkUninstallEntry.cs:379
}
}
// Check for deadlocks during silent uninstall. Prevents the task from getting stuck
// idefinitely on stuck uninstallers and unrelated processes spawned by uninstallers.
if (checkCounters)
{
var processNames = SafeGetProcessNames(watchedProcesses);
if (TestUninstallerForStalls(processNames))
idleCounter++;
else
idleCounter = 0;
// Kill the uninstaller (and children) if they were idle/stalled for too long
if (idleCounter > 30)
{
KillProcesses(watchedProcesses);
throw new IOException(Localisation.UninstallError_UninstallerTimedOut);
}
}
else Thread.Sleep(1000);
// Kill the uninstaller (and children) if user told us to or if it was idle for too long
if (_skipLevel == SkipCurrentLevel.Terminate)
{
if (UninstallerEntry.UninstallerKind == UninstallerType.Msiexec)
watchedProcesses.AddRange(Process.GetProcessesByName("Msiexec"));
KillProcesses(watchedProcesses);
break;
}
}
if (_skipLevel == SkipCurrentLevel.None)
{
var exitVar = uninstaller.ExitCode;
View on GitHub (pinned to 608321de98)
Solutions
- Increase the stall tolerance / run the same uninstaller interactively (non-quiet) to see what it is waiting on, then supply the right silent flag or pre-answer its prompt.
- Close other apps that may hold files the uninstaller needs, and run with elevation.
- Catch IOException for this timeout, mark the entry as 'needs manual uninstall', and continue the bulk run rather than aborting all remaining entries.
Example fix
// before
var result = manager.RunUninstaller(entry, options);
// after
try { var result = manager.RunUninstaller(entry, options); }
catch (IOException ex) when (ex.Message.Contains(Localisation.UninstallError_UninstallerTimedOut))
{
entry.MarkManualUninstall("Uninstaller stalled; run interactively.");
continue;
} Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try { manager.RunUninstaller(entry, options); }
catch (IOException ex) when (ex.Message.Contains(Localisation.UninstallError_UninstallerTimedOut))
{
entry.MarkManualUninstall("Uninstaller stalled; run interactively.");
} Prevention
- Run interactive (non-quiet) first to discover hidden prompts the silent flags do not suppress.
- Close other apps and services that may hold files the uninstaller needs.
- Surface a 'continue bulk run' option on timeout instead of aborting.
When it happens
Trigger: A spawned uninstaller process (or its child processes) is running but making no progress — e.g. it opened a modal dialog waiting for input, deadlocked, or is waiting on a network resource — so TestUninstallerForStalls keeps returning true and the counter exceeds 30 within the ~1s poll interval.
Common situations: Uninstaller shows a hidden 'Are you sure?' prompt behind the main window; the installer is waiting for a locked file; a child process (e.g. Msiexec) is idle on a custom action; silent uninstall flags were not honoured by the vendor installer.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Uninstaller returned error code: {exitVar}
- This application does not have a valid uninstaller
- regedit.exe failed to execute properly
- WMI query has hung while collecting Windows Features, try re
- Key "{FullRegKeyPath}" doesn't exist or can't be accessed
AI-assisted analysis of BCUninstaller/Bulk-Crap-Uninstaller@608321de98 (2026-08-13).
Data as JSON: /api/errors/933f7d6167c3cbe3.
Report an issue: GitHub.