Problem type
Windows file-locking / process-lifecycle bug: the plugin installer cannot remove a managed plugin's directory because that directory is locked by the plugin's own MCP server child process, which kimi-code itself spawned and keeps running during the session.
Error
Error: Failed to install Kimi Datasource: [internal] EBUSY: resource busy or locked, rmdir
'C:\Users\38623\.kimi-code\plugins\managed\kimi-datasource'
Root cause analysis
-
A managed plugin declares an MCP server whose working directory is the plugin directory itself. Example from ~/.kimi-code/plugins/managed/kimi-datasource/kimi.plugin.json:
"mcpServers": {
"data": {
"command": "node",
"args": ["./bin/kimi-datasource.mjs"],
"cwd": "./"
}
}
-
While a kimi-code session is running, the plugin's MCP server stays alive as a child process. Verified on the affected machine:
kimi.exe (PID 43740) __plugin_run_node ./bin/kimi-datasource.mjs
This process's current working directory is C:\Users\38623\.kimi-code\plugins\managed\kimi-datasource, and it also holds an open handle on bin/kimi-datasource.mjs.
-
On Windows (unlike POSIX), a directory that is any process's working directory — or that contains files with open handles — cannot be removed. fs.rmdir/rm -rf on it fails with EBUSY: resource busy or locked.
-
When kimi-code tries to install/update the plugin, it removes the existing directory without first stopping the plugin's MCP server child process (or without waiting for it to exit), so the rmdir deterministically fails with EBUSY.
-
This creates a catch-22 for the user:
- Keep the session running → the MCP child process holds the lock → update fails with EBUSY.
- Kill the process/session → the CLI that would perform the update is also gone → update still doesn't happen.
Reproduction
- On Windows, install a managed plugin that runs an MCP server (e.g. Kimi Datasource).
- Start a kimi-code session (the plugin's MCP server child process starts, with cwd inside the plugin directory).
- Trigger a plugin update/reinstall (from
/plugins or wherever the update is offered).
- Observe:
Failed to install ...: [internal] EBUSY: resource busy or locked, rmdir '<plugin dir>'.
Environment
- OS: Windows 11 (10.0.26200.8875), x86_64
- kimi-code version: 0.30.0
- Plugin: kimi-datasource 3.3.0 (managed)
- Install path:
C:\Users\<user>\.kimi-code\plugins\managed\kimi-datasource
Suggested fixes
Any of these would resolve it:
- Stop-then-reinstall: before removing a managed plugin directory, terminate that plugin's MCP server child process(es) and wait for exit (with a timeout + force kill fallback), then
rmdir.
- Rename-then-swap (more robust on Windows): rename the old directory to a sibling temp name (rename often works even when the dir is busy), install the new version, and delete the old directory on next startup when nothing holds it.
- Deferred deletion: if
rmdir fails with EBUSY/EPERM, schedule the cleanup for next CLI launch instead of hard-failing the whole install.
- Retry with backoff: Windows AV/indexer locks are often transient; retrying
rmdir a few times with delay is a common mitigation — though for this specific bug the lock is held by kimi-code's own child for the whole session, so retries alone won't help without fixing the lifecycle ordering.
Note: the cwd: "./" in the plugin manifest makes the plugin directory itself the MCP server's working directory, which guarantees the lock for the entire session. Even without cwd, the running node process keeps an open handle on bin/kimi-datasource.mjs, which blocks removal of that file on Windows too.
Workaround for affected users
Fully exit all kimi-code sessions, then manually delete ~/.kimi-code/plugins/managed/kimi-datasource, then restart kimi-code and reinstall the plugin. (If a stale kimi.exe ... __plugin_run_node process survives, kill it first.)
Problem type
Windows file-locking / process-lifecycle bug: the plugin installer cannot remove a managed plugin's directory because that directory is locked by the plugin's own MCP server child process, which kimi-code itself spawned and keeps running during the session.
Error
Root cause analysis
A managed plugin declares an MCP server whose working directory is the plugin directory itself. Example from
~/.kimi-code/plugins/managed/kimi-datasource/kimi.plugin.json:While a kimi-code session is running, the plugin's MCP server stays alive as a child process. Verified on the affected machine:
This process's current working directory is
C:\Users\38623\.kimi-code\plugins\managed\kimi-datasource, and it also holds an open handle onbin/kimi-datasource.mjs.On Windows (unlike POSIX), a directory that is any process's working directory — or that contains files with open handles — cannot be removed.
fs.rmdir/rm -rfon it fails withEBUSY: resource busy or locked.When kimi-code tries to install/update the plugin, it removes the existing directory without first stopping the plugin's MCP server child process (or without waiting for it to exit), so the
rmdirdeterministically fails with EBUSY.This creates a catch-22 for the user:
Reproduction
/pluginsor wherever the update is offered).Failed to install ...: [internal] EBUSY: resource busy or locked, rmdir '<plugin dir>'.Environment
C:\Users\<user>\.kimi-code\plugins\managed\kimi-datasourceSuggested fixes
Any of these would resolve it:
rmdir.rmdirfails with EBUSY/EPERM, schedule the cleanup for next CLI launch instead of hard-failing the whole install.rmdira few times with delay is a common mitigation — though for this specific bug the lock is held by kimi-code's own child for the whole session, so retries alone won't help without fixing the lifecycle ordering.Note: the
cwd: "./"in the plugin manifest makes the plugin directory itself the MCP server's working directory, which guarantees the lock for the entire session. Even withoutcwd, the runningnodeprocess keeps an open handle onbin/kimi-datasource.mjs, which blocks removal of that file on Windows too.Workaround for affected users
Fully exit all kimi-code sessions, then manually delete
~/.kimi-code/plugins/managed/kimi-datasource, then restart kimi-code and reinstall the plugin. (If a stalekimi.exe ... __plugin_run_nodeprocess survives, kill it first.)