From 0ede5e16d08425cbf853a378b6c4afb1a2e0ecc5 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 24 Jun 2026 15:17:14 +0000 Subject: [PATCH 1/2] fix(nodejs plugin): warn when Corepack is unavailable The nodejs plugin's setup-corepack init_hook ran `corepack enable` and swallowed any failure silently. On nodejs-slim and Node.js 25+, which no longer bundle Corepack, this left users with a cryptic "corepack: command not found" / "yarn: command not found" at shell startup and no indication of the cause. Detect the missing-binary (ENOENT) case and print actionable guidance pointing users to `devbox add corepack`, then cleanly skip package manager activation. The happy path (Corepack present) is unchanged. Fixes #2791 Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01MEAWvyABicqkLncj6irnQq --- plugins/nodejs.json | 2 +- plugins/nodejs/setup-corepack.mjs | 35 +++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/plugins/nodejs.json b/plugins/nodejs.json index bc398057744..ea18dc9c2c2 100644 --- a/plugins/nodejs.json +++ b/plugins/nodejs.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/main/.schema/devbox-plugin.schema.json", - "version": "0.0.4", + "version": "0.0.5", "name": "nodejs", "readme": "Devbox automatically configures Corepack for Nodejs when DEVBOX_COREPACK_ENABLED=1. You can install Yarn or Pnpm by adding them to your `package.json` file using `packageManager`\nCorepack binaries will be installed in your local `.devbox` directory\n\nWhen Corepack is enabled, Devbox also activates the package manager pinned in your `package.json` `packageManager` field automatically. Set DEVBOX_DISABLE_NODEJS_PACKAGE_MANAGER_AUTODETECT=1 to disable this behavior.\n\nNote: newer versions of Nodejs (25+) no longer bundle Corepack, so you must add the `corepack` package to your devbox.json separately for Corepack to be available.", "env": { diff --git a/plugins/nodejs/setup-corepack.mjs b/plugins/nodejs/setup-corepack.mjs index 1ca1dd175cc..734680bd771 100644 --- a/plugins/nodejs/setup-corepack.mjs +++ b/plugins/nodejs/setup-corepack.mjs @@ -27,8 +27,12 @@ if (!corepackBinDir) { process.exit(0); } -// Enable Corepack, installing the pnpm/yarn/npm shims into corepackBinDir. -run("corepack", ["enable", "--install-directory", corepackBinDir]); +// Enable Corepack, installing the pnpm/yarn/npm shims into corepackBinDir. If +// Corepack itself is missing, stop here: there is nothing to activate, and +// run() has already printed actionable guidance. +if (!run("corepack", ["enable", "--install-directory", corepackBinDir])) { + process.exit(0); +} // Activate the package manager pinned in package.json's "packageManager" field. activatePinnedPackageManager(); @@ -64,12 +68,31 @@ function activatePinnedPackageManager() { run("corepack", ["prepare", "--activate", packageManager]); } -// Run a command, inheriting stdio so Corepack's output is visible. Failures -// must not block shell initialization. +// Run a command, inheriting stdio so Corepack's output is visible. Returns +// true on success and false on failure. Failures must not block shell +// initialization, so errors are reported but never rethrown. function run(command, args) { try { execFileSync(command, args, { stdio: "inherit" }); - } catch { - // Ignore: e.g. Corepack unavailable, or offline during activation. + return true; + } catch (err) { + // ENOENT means the command itself is missing. For Corepack this happens + // with nodejs-slim and Node.js 25+, which no longer bundle it (see issue + // #2791). Without a message, the user is left with a cryptic + // "command not found" for yarn/pnpm and no idea why, so point them at the + // fix instead of failing silently. + if (err && err.code === "ENOENT") { + console.error( + `[devbox] nodejs plugin: \`${command}\` was not found, so Corepack-managed ` + + `package managers (such as yarn and pnpm) will be unavailable.`, + ); + console.error( + `[devbox] Your Node.js package does not bundle Corepack (e.g. nodejs-slim, ` + + `or Node.js 25+). Add it explicitly with \`devbox add corepack\` to enable it.`, + ); + return false; + } + // Other failures (e.g. offline during activation) are non-fatal. + return false; } } From 162b21d4eb74fd36fccc54da7815fe9d7f0a5e9f Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 24 Jun 2026 15:22:01 +0000 Subject: [PATCH 2/2] fix(nodejs plugin): only skip Corepack activation when binary is missing Address review feedback: the previous revision skipped package-manager activation whenever `corepack enable` failed for any reason. Restrict the early-exit to the missing-binary (ENOENT) case so transient, non-ENOENT failures remain non-fatal and still attempt activation, matching the plugin's prior behavior. Move the missing-Corepack guidance into a dedicated warnCorepackMissing() helper and restore run() to its simple swallow-all contract. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01MEAWvyABicqkLncj6irnQq --- plugins/nodejs/setup-corepack.mjs | 62 +++++++++++++++++-------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/plugins/nodejs/setup-corepack.mjs b/plugins/nodejs/setup-corepack.mjs index 734680bd771..e9a4f077084 100644 --- a/plugins/nodejs/setup-corepack.mjs +++ b/plugins/nodejs/setup-corepack.mjs @@ -27,11 +27,22 @@ if (!corepackBinDir) { process.exit(0); } -// Enable Corepack, installing the pnpm/yarn/npm shims into corepackBinDir. If -// Corepack itself is missing, stop here: there is nothing to activate, and -// run() has already printed actionable guidance. -if (!run("corepack", ["enable", "--install-directory", corepackBinDir])) { - process.exit(0); +// Enable Corepack, installing the pnpm/yarn/npm shims into corepackBinDir. +try { + execFileSync("corepack", ["enable", "--install-directory", corepackBinDir], { + stdio: "inherit", + }); +} catch (err) { + if (err && err.code === "ENOENT") { + // Corepack isn't bundled with this Node.js package (e.g. nodejs-slim, or + // Node.js 25+, see issue #2791). Without a message the user is later left + // with a cryptic "command not found" for yarn/pnpm and no idea why, so warn + // with actionable guidance and stop: there is nothing to activate. + warnCorepackMissing(); + process.exit(0); + } + // Any other failure (e.g. a non-zero exit while offline) is non-fatal: fall + // through and still attempt activation, as the plugin did before. } // Activate the package manager pinned in package.json's "packageManager" field. @@ -68,31 +79,26 @@ function activatePinnedPackageManager() { run("corepack", ["prepare", "--activate", packageManager]); } -// Run a command, inheriting stdio so Corepack's output is visible. Returns -// true on success and false on failure. Failures must not block shell -// initialization, so errors are reported but never rethrown. +// Run a command, inheriting stdio so Corepack's output is visible. Failures +// must not block shell initialization, so errors are reported but never +// rethrown. function run(command, args) { try { execFileSync(command, args, { stdio: "inherit" }); - return true; - } catch (err) { - // ENOENT means the command itself is missing. For Corepack this happens - // with nodejs-slim and Node.js 25+, which no longer bundle it (see issue - // #2791). Without a message, the user is left with a cryptic - // "command not found" for yarn/pnpm and no idea why, so point them at the - // fix instead of failing silently. - if (err && err.code === "ENOENT") { - console.error( - `[devbox] nodejs plugin: \`${command}\` was not found, so Corepack-managed ` + - `package managers (such as yarn and pnpm) will be unavailable.`, - ); - console.error( - `[devbox] Your Node.js package does not bundle Corepack (e.g. nodejs-slim, ` + - `or Node.js 25+). Add it explicitly with \`devbox add corepack\` to enable it.`, - ); - return false; - } - // Other failures (e.g. offline during activation) are non-fatal. - return false; + } catch { + // Ignore: e.g. Corepack unavailable, or offline during activation. } } + +// Print actionable guidance when the `corepack` binary is missing, so the user +// understands why yarn/pnpm aren't available and how to fix it. +function warnCorepackMissing() { + console.error( + "[devbox] nodejs plugin: `corepack` was not found, so Corepack-managed " + + "package managers (such as yarn and pnpm) will be unavailable.", + ); + console.error( + "[devbox] Your Node.js package does not bundle Corepack (e.g. nodejs-slim, " + + "or Node.js 25+). Add it explicitly with `devbox add corepack` to enable it.", + ); +}