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 <noreply@anthropic.com>
This commit is contained in:
Cameron Pak
2026-03-07 08:55:37 -06:00
parent 980886b5c5
commit 48d432ddb2
+10 -2
View File
@@ -66,6 +66,11 @@ async function loadConfigFile(configFilePath: string): Promise<CliBkndConfig> {
} }
function reexecUnderBun(): never { 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 const bunPath = process.env.BUN_INSTALL
? path.join(process.env.BUN_INSTALL, "bin", "bun") ? path.join(process.env.BUN_INSTALL, "bin", "bun")
: "bun"; : "bun";
@@ -79,7 +84,10 @@ function reexecUnderBun(): never {
); );
try { try {
execFileSync(bunPath, args, { stdio: "inherit" }); execFileSync(bunPath, args, {
stdio: "inherit",
env: { ...process.env, __BKND_REEXEC: "1" },
});
process.exit(0); process.exit(0);
} catch (e: any) { } catch (e: any) {
if (e.status != null) { if (e.status != null) {
@@ -141,7 +149,7 @@ export async function makeAppFromEnv(options: Partial<RunOptions> = {}) {
const config = await loadConfigFile(configFilePath); const config = await loadConfigFile(configFilePath);
app = await makeConfigApp(config, options.server); app = await makeConfigApp(config, options.server);
} catch (e) { } catch (e) {
if (e instanceof ReferenceError && e.message === "Bun is not defined") { if (e instanceof ReferenceError && /\bBun\b.*not defined/.test(e.message)) {
reexecUnderBun(); reexecUnderBun();
} }
console.error("Failed to load config:", e); console.error("Failed to load config:", e);