#1033·ai-toolkit

Windows: stale cron worker survives UI shutdown, breaks next startup with EPERM on prisma generate

Author: SilentLuxRayCreated Sep 9, 2026Updated Sep 9, 2026

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

  1. Start the UI with run_windows.bat
  2. Close the terminal window (rather than stopping it with Ctrl+C)
  3. Start run_windows.bat again

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:

powershell
Get-Process | Where-Object { $_.Modules.FileName -like '*query_engine-windows*' }

   Id ProcessName
   -- -----------
37684 node          # -> node dist/cron/worker.js

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

json
"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

  1. Add -k (--kill-others) to the start script, so the worker is terminated together with the supervisor — matching what dev already does.
  2. Optionally, make update_db resilient: on EPERM, remove stale query_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.

powershell
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 SilentlyContinue