Windows minion will not stop
When a Windows minion update fails and corrupts the package, minion-cli-win stop may fail at the .env read or agent-API call stage and leave the services running. Because NSSM (the Windows service manager) keeps respawning node.exe, files under node_modules\@geekbeer\minion\ stay locked, and npm uninstall -g @geekbeer/minion also fails.
First, try stop --force (v3.43.0+)
Section titled “First, try stop --force (v3.43.0+)”Starting in v3.43.0, the --force flag bypasses graceful shutdown entirely and force-stops every minion service and process. Run from an elevated PowerShell (Administrator).
minion-cli-win stop --forceIt performs the following steps in order:
- Rewrite NSSM
AppExittoExitandAppThrottle 0to disable auto-restart temporarily sc.exe stopforminion-agent/minion-websockify/minion-cloudflared/minion-vncStop-Process -Forcefortvnserver/websockify/cloudflared- Kill every
node.exewhoseWin32_Process.CommandLinematches a minion script - Restore NSSM
AppExit Default Restartso a subsequentminion-cli-win startbehaves normally
In-flight chats and workflows are aborted, and the offline heartbeat to HQ (/api/shutdown) is skipped — the HQ dashboard will continue to show the minion as online until the heartbeat timeout fires (tens of seconds to a few minutes).
When stop --force is also unusable (manual procedure)
Section titled “When stop --force is also unusable (manual procedure)”If the CLI itself will not start, or you are on a version older than v3.43.0, run the equivalent steps manually from an elevated PowerShell.
# 1. Disable NSSM auto-restart, then stop and remove each service$nssm = "$env:USERPROFILE\.minion\nssm.exe" # vendor build: %APPDATA%\npm\node_modules\@geekbeer\minion\win\vendor\nssm.exeforeach ($svc in 'minion-agent','minion-websockify','minion-cloudflared','minion-vnc') { & $nssm set $svc AppExit Default Exit 2>$null & $nssm set $svc AppThrottle 0 2>$null sc.exe stop $svc 2>$null Start-Sleep -Seconds 2 & $nssm remove $svc confirm 2>$null}
# 2. Remove scheduled tasksUnregister-ScheduledTask -TaskName MinionWSL -Confirm:$false -ErrorAction SilentlyContinueUnregister-ScheduledTask -TaskName MinionVNC -Confirm:$false -ErrorAction SilentlyContinue
# 3. Kill remaining helper processesStop-Process -Name tvnserver,websockify,cloudflared -Force -ErrorAction SilentlyContinue
# 4. Kill only minion-related node.exe processes (leave unrelated node alone)Get-CimInstance Win32_Process -Filter "Name='node.exe'" | Where-Object { $_.CommandLine -match 'minion|@geekbeer\\minion|terminal-server|workflow-runner|routine-runner|wsl-session-server' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }If files remain locked
Section titled “If files remain locked”The steps above release locks in almost every case. If something is still holding the package files, identify the responsible process:
$pkg = "$env:APPDATA\npm\node_modules\@geekbeer\minion" # global install locationGet-Process | Where-Object { $_.Modules.FileName -like "$pkg\*" } | Select-Object Id, ProcessNameIf you have Sysinternals Handle, it pins down the offender even more reliably:
handle64.exe -nobanner $pkgStop the listed PIDs with Stop-Process -Id <PID> -Force. As a last resort, an OS reboot always works — set Set-Service minion-agent -StartupType Disabled before rebooting so the service does not start back up and re-lock the files.
Reinstalling the package
Section titled “Reinstalling the package”Once services and processes are stopped, reinstall normally.
npm uninstall -g @geekbeer/minionRemove-Item -Recurse -Force "$env:APPDATA\npm\node_modules\@geekbeer\minion" -ErrorAction SilentlyContinuenpm install -g @geekbeer/minionminion-cli-win setupDo not use stop --force as the default
Section titled “Do not use stop --force as the default”Because stop --force skips graceful shutdown completely, it has the following side effects:
- In-flight chats, workflows, and terminal sessions are aborted abruptly
- The offline heartbeat is not sent to HQ, so the dashboard shows the minion as online until heartbeat timeout (tens of seconds to a few minutes)
- Logs and SQLite writes in flight may be left in a partial state
Continue to use minion-cli-win stop (graceful) for normal operations. --force is an emergency fallback for when graceful stop is broken, not a routine command.