Conversation
The static `import` of `dist/pnpm.mjs` in `bin/pnpm.mjs` was hoisted by the ES module loader and parsed before the version check below it, causing pnpm to crash with `SyntaxError: Invalid regular expression flags` on Node.js versions older than the bundle's syntax target instead of printing a clear "requires Node.js v22.13" error. Switching to a dynamic `await import()` lets the version check run first.
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a pnpm CLI startup failure on unsupported Node.js versions by ensuring the Node.js version guard runs before the bundled CLI module is parsed/loaded, avoiding confusing syntax errors from newer syntax in bundled dependencies.
Changes:
- Replaced a hoisted static ESM import with a dynamic
await import()inpnpm/bin/pnpm.mjsso the version check executes first. - Added a changeset documenting the user-facing fix for the incorrect
SyntaxErrorbehavior on older Node.js versions.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| pnpm/bin/pnpm.mjs | Switches bundle loading to dynamic import to prevent pre-check parsing on unsupported Node.js versions. |
| .changeset/pnpm-bin-version-check-hoisting.md | Adds a patch changeset describing the crash fix and linking to the reported issue. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
zkochan
added a commit
that referenced
this pull request
May 8, 2026
The static `import` of `dist/pnpm.mjs` in `bin/pnpm.mjs` was hoisted by the ES module loader and parsed before the version check below it, causing pnpm to crash with `SyntaxError: Invalid regular expression flags` on Node.js versions older than the bundle's syntax target instead of printing a clear "requires Node.js v22.13" error. Switching to a dynamic `await import()` lets the version check run first.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #11546.
The Node.js version check in
pnpm/bin/pnpm.mjswas effectively dead code. It used a staticimportto load the bundleddist/pnpm.mjs, and ESM hoists static imports — so the bundle was parsed before theif (major < 22 ...)block could run. On Node.js versions older than the bundle's syntax target (e.g. Node 18 hitting a regex with the/vflag in a transitive dependency), users got a confusingSyntaxError: Invalid regular expression flagsinstead of the intendedERROR: This version of pnpm requires at least Node.js v22.13message.Switching to
await import('../dist/pnpm.mjs')makes the load order match the source order, so the version check runs first and exits with a friendly error.The other entry points are unaffected:
pnpm/bin/pnpm.cjs(Corepack shim) already uses dynamicimport('./pnpm.mjs')and goes through the fixed file.pnpm/pnpm.cjs(@pnpm/exeSEA entry) ships its own embedded Node.js, so the version check isn't needed there.Test plan
importof a file containing/a/vparses before any code in the importing module runs, even when an earlyprocess.exit(1)should have prevented it.await import(), the version-checkconsole.error+process.exit(1)runs first and the bundle is never parsed.pnpm --versionon a supported Node.js (24+) still works.Written by an agent (Claude Code, claude-opus-4-7).
Summary by CodeRabbit