From 48d432ddb2d585ba6ce1759ea455298ed7bb262d Mon Sep 17 00:00:00 2001 From: Cameron Pak Date: Sat, 7 Mar 2026 08:55:37 -0600 Subject: [PATCH] fix(cli): add re-exec loop guard and robust Bun error matching Prevent infinite re-exec loop when Bun is installed but config still fails. Use regex for error matching instead of exact string comparison. Co-Authored-By: Claude Opus 4.6 --- app/src/cli/commands/run/run.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/cli/commands/run/run.ts b/app/src/cli/commands/run/run.ts index 050fd8b1..8a507b64 100644 --- a/app/src/cli/commands/run/run.ts +++ b/app/src/cli/commands/run/run.ts @@ -66,6 +66,11 @@ async function loadConfigFile(configFilePath: string): Promise { } function reexecUnderBun(): never { + if (process.env.__BKND_REEXEC) { + console.error(c.red("Config requires Bun but still failed under Bun runtime.")); + process.exit(1); + } + const bunPath = process.env.BUN_INSTALL ? path.join(process.env.BUN_INSTALL, "bin", "bun") : "bun"; @@ -79,7 +84,10 @@ function reexecUnderBun(): never { ); try { - execFileSync(bunPath, args, { stdio: "inherit" }); + execFileSync(bunPath, args, { + stdio: "inherit", + env: { ...process.env, __BKND_REEXEC: "1" }, + }); process.exit(0); } catch (e: any) { if (e.status != null) { @@ -141,7 +149,7 @@ export async function makeAppFromEnv(options: Partial = {}) { const config = await loadConfigFile(configFilePath); app = await makeConfigApp(config, options.server); } catch (e) { - if (e instanceof ReferenceError && e.message === "Bun is not defined") { + if (e instanceof ReferenceError && /\bBun\b.*not defined/.test(e.message)) { reexecUnderBun(); } console.error("Failed to load config:", e);