From dc420ba5a27a7ce9815a299cd7bb529f651a72da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Sun, 16 Aug 2026 10:56:26 +0000 Subject: [PATCH] stop assuming bunx is on the service's PATH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Executable not found in $PATH: "bunx"` — installing music died there, after the clone and after apt had installed ffmpeg. My bug, one commit old: the schema step spawned `bunx drizzle-kit`. PM2 starts the platform with a PATH that has `bun` and not `bunx`. That is a perfectly normal way for a service to be started — a symlink into /usr/local/bin for the runtime and nothing else — and an install has no business depending on which of a runtime's shims someone happened to link. So neither name is looked up now. `process.execPath` is the interpreter already running this code, so it cannot be missing, and drizzle-kit is invoked by path through `node_modules/.bin/drizzle-kit` rather than by resolution. A missing CLI there is reported as "run bun install" instead of as a PATH mystery. Verified the way the claim demands: re-ran the schema push under `env -i PATH=/usr/bin:/bin`, where `Bun.which('bunx')` and `Bun.which('bun')` both return nothing. It works. The previous run proved nothing, because bunx was still there. Worth noting for the next spawn added to this path: `git`, `pm2` and `sudo` are still PATH lookups, and they are the ones that were already working on the machines we have. Anything new should follow this pattern instead. tsgo clean, frontend builds, 873 pass / 7 fail unchanged. Co-Authored-By: Claude Opus 5 --- src/servers/plugins/schema.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/servers/plugins/schema.ts b/src/servers/plugins/schema.ts index bf3243f7..e9b86557 100644 --- a/src/servers/plugins/schema.ts +++ b/src/servers/plugins/schema.ts @@ -127,7 +127,21 @@ export default defineConfig({ writeFileSync(configPath, config); // `generate`, never `push`. See the note above this function. - const generated = await runLogged(['bunx', 'drizzle-kit', 'generate', `--config=${basename(configPath)}`], { + // + // Invoked through THIS process's own bun and drizzle-kit's bin symlink, never through `bunx`. A + // member's install failed with `Executable not found in $PATH: "bunx"` — the platform runs under PM2 + // with a PATH that has `bun` and not `bunx`, which is a normal way for a service to be started and + // not something an install should depend on. `process.execPath` is the interpreter already running, + // so it cannot be missing, and `node_modules/.bin/drizzle-kit` is a path rather than a lookup. + const cli = join(PLATFORM_DIR, 'node_modules/.bin/drizzle-kit'); + if (!existsSync(cli)) { + return { + ok: false, + ms: Date.now() - started, + output: `drizzle-kit is not installed at ${cli} — run \`bun install\` in the platform directory`, + }; + } + const generated = await runLogged([process.execPath, cli, 'generate', `--config=${basename(configPath)}`], { cwd: dbDir, onLog, });