Repository navigation
fix: show a clear error when an unsupported Node.js version crashes the CLI - #3995
michaelmalave wants to merge 4 commits into
Conversation
…crashes the CLI on load On Node < 20 most commands crash while loading dependencies that use the regex v flag (Sentry CLI-5K7). Replace execute() in bin/run.js with run/flush/handle and turn that specific SyntaxError into an actionable HEROKU_UNSUPPORTED_NODE error. Classify it as expected so it goes to Honeycomb only.
… guard match bin/run.js falls back to handle(error) if the guard helper import fails; isUnsupportedNodeCrash now matches only "Invalid regular expression flags", so runtime bad-pattern SyntaxErrors on Node <20 still reach Sentry.
tlowrimore-heroku
left a comment
There was a problem hiding this comment.
A couple of questions:
- for the
MIN_NODE_MAJORvalue, does this need to match the value of theengines.nodeproperty inpackage.json? If so, should we read that value frompackage.json, and let that be the single source of truth? - Assuming the answer to the first question is, “yes”, do we also need to account for minor versions? Recently, we ran into an issue while attempting to upgrade some OTel dependencies that required a minimum node version of
20.6. We didn’t update to20.6as it’s a breaking change. I ask as this is top-of-mind, and would likely need to be accounted for, to allow use of minor versions in theengines.nodeproperty.
…rted-Node message The message now reads engines.node from package.json at runtime and shows it as written, falling back to generic wording if it can't be read. The crash check keeps its own constant, renamed FIRST_NODE_MAJOR_WITH_V_FLAG, since it reflects when Node began parsing the regex v flag rather than the supported range. The engines drift test is removed because nothing duplicates engines any more.
|
Good questions, and they're addressed in 53ec204.
The guard isn't affected by minor-version floors: a Node 20.5 failure from a dependency that needs 20.6 is a different error and passes through unchanged. |
Summary
On Node.js 18 or older, most Heroku CLI commands crash with the raw message
SyntaxError: Invalid regular expression flagsand no hint about what to do. A dependency (string-width@8, pulled in through@oclif/table) needs Node.js 20 or later, even though the CLI already declaresengines >=20. This is Sentry issue CLI-5K7, about 380K events per day, all from Node 16/18.With this change, when Node.js is below 20 and the crash is that specific error, the CLI shows a clear message instead:
› Error: Node.js v18.20.8 is not supported. The Heroku CLI requires Node.js >=20. Upgrade Node.js, or install the standalone Heroku CLI, which includes its own Node.js: https://devcenter.heroku.com/articles/heroku-cliThe "requires" part is read from
engines.nodeinpackage.jsonwhen the error happens and shown as written, so it always matches what the CLI declares. If that file can't be read, the message says "a newer version of Node.js" instead.It uses
Code: HEROKU_UNSUPPORTED_NODEand the exit code stays 1. Commands that already work on Node 18 (about 109 of 360 core commands, such as--version,--help,auth:*,logs,run,ps:scale,config:unset) are untouched. Everything else is handled exactly as before.This condition is now treated as an expected error, so it is reported to Honeycomb only and no longer to Sentry (the same mechanism as the non-interactive login error). Already-released versions 11.10 to 11.12 cannot get this fix, so Sentry volume from those installs continues until users update.
Only the exact "Invalid regular expression flags" crash is treated this way, so an ordinary bad-pattern error on an old Node still shows up in Sentry as before. If the small helper that builds this message ever fails to load (for example a stale build), the CLI falls back to showing the original error instead of losing it.
Implementation: a new dependency-free
src/lib/check-node-version.ts;bin/run.jsnow uses oclifrun/flush/handle(whatexecute()does internally) with a catch for this case; and a new rule inisExpectedError.Type of Change
Breaking Changes (major semver update)
!after your change type to denote a change that breaks current behaviorFeature Additions (minor semver update)
Patch Updates (patch semver update)
Testing
Notes:
npm run test:ci:unit: 2424 passing, 9 failing. The same 9 fail on pristine main (8version:infotests from a marked-terminal/chalk module-resolution error, 1domainstest), unrelated to this change.Steps:
heroku appsshows the unsupported-Node message and exits 1.heroku --versionandheroku auth:tokenstill work (exit 0).Screenshots (if applicable)
Related Issues
GitHub issue: N/A
GUS work item: N/A