Windows: stale cron worker survives UI shutdown, breaks next startup with EPERM on prisma generate
Windows: stale cron worker survives UI shutdown, breaking the next startup with EPERM on prisma generate
Environment
- Windows 11
- ai-toolkit commit
fb7c14b(2026-09-08) - Started via
run_windows.bat
Steps to reproduce
- Start the UI with
run_windows.bat - Close the terminal window (rather than stopping it with Ctrl+C)
- Start
run_windows.batagain
Actual behaviour
Startup fails during update_db:
> [email protected] update_db
> npx prisma generate && npx prisma db push
Prisma schema loaded from prisma\schema.prisma
Error:
EPERM: operation not permitted, rename
'X:\Training\ai-toolkit\\\ui\node_modules\.prisma\client\query_engine-windows.dll.node.tmp34292'
-> 'X:\Training\ai-toolkit\\\ui\node_modules\.prisma\client\query_engine-windows.dll.node'The UI never starts. Each failed attempt leaves a ~19 MB query_engine-windows.dll.node.tmp*
file behind — I had three of them (58 MB) before cleaning up manually.
Cause
Node processes from the previous session are still running, and one of them holds
query_engine-windows.dll.node open. Windows refuses to rename a file that is in use, so
prisma generate cannot swap in the new query engine.
Confirmed which process holds the handle:
Get-Process | Where-Object { $_.Modules.FileName -like '*query_engine-windows*' }
Id ProcessName
-- -----------
37684 node # -> node dist/cron/worker.jsOn my machine seven ai-toolkit node processes were still alive, the oldest from the
previous evening.
The likely reason is in ui/package.json: dev passes -k to concurrently, but
start does not.
"dev": "concurrently -k -n WORKER,UI \"ts-node-dev ... cron/worker.ts\" \"ts-node-dev ... cron/fileServer.ts dev --port 3000\"",
"start": "concurrently --restart-tries -1 --restart-after 1000 -n WORKER,UI \"node dist/cron/worker.js\" \"node dist/cron/fileServer.js start --port 8675\""Without -k, killing the supervisor leaves its children running, and --restart-tries -1
respawns the worker if it does go down. On Windows, closing the console window does not
reliably terminate the whole process tree, so the worker outlives the UI.
Proposed fix
- Add
-k(--kill-others) to thestartscript, so the worker is terminated together with the supervisor — matching whatdevalready does. - Optionally, make
update_dbresilient: onEPERM, remove stalequery_engine-*.tmp*files and retry once. This also prevents the leftover temp files from accumulating.
Workaround
Kill only ai-toolkit's node processes before starting. Filtering on the command line
matters: other applications run node.exe too — on my machine Adobe Creative Cloud does,
and killing that one would be an unwelcome surprise.
Get-CimInstance Win32_Process -Filter "Name='node.exe'" |
Where-Object { $_.CommandLine -like '*ai-toolkit*' } |
ForEach-Object { Stop-Process -Id $_.ProcessId -Force }
Remove-Item "ui\node_modules\.prisma\client\*.tmp*" -Force -ErrorAction SilentlyContinueSource: ostris/ai-toolkit