Skip to content

fix(plugin-ci): replace npm 10.9.x on Node 22 runners - #3069

Merged
tkurki merged 1 commit into
SignalK:masterfrom
dirkwa:fix-plugin-ci-npm10-peer-crash
Sep 21, 2026
Merged

tkurki merged 1 commit into
SignalK:masterfrom
dirkwa:fix-plugin-ci-npm10-peer-crash

Conversation

@dirkwa

@dirkwa dirkwa commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Every plugin-ci.yml Node 22 job currently fails at dependency install, before a single test runs, for any plugin that depends on vitest — regardless of what the pull request changed.

npm error Cannot read properties of null (reading 'edgesOut')
    at #loadPeerSet (@npmcli/arborist/lib/arborist/build-ideal-tree.js:1289:38)

npm walks vitest's optional peer graph and crashes on @vitest/browser-playwright, which is not itself being installed. It is upstream npm/cli#9960 and #9787, both still open.

The retry helper already in this workflow cannot clear it: the crash is deterministic, not transient.

Scope

I hit this across several plugin repos and reproduced it on clean clones of their unmodified default branches, so it is not specific to one plugin or one pull request. Measured:

Node npm clean npm install
20.20.2 10.8.2 ok
22.22.0 10.9.4 crash
22.23.2 10.9.8 crash
22.23.2 11.19.1 ok
22.23.2 12.0.2 ok
24.19.0 12.0.2 ok

So the boundary is npm 10.9.x specifically — not Node 22, and not npm 10 generally.

The change

Both Node-setup jobs (the desktop matrix and the signalk-server integration matrix) replace that minor with npm 11.

The test is an exact 10.9.* match rather than "older than 11". Node 20 ships npm 10.8.2, which resolves the same tree cleanly, so upgrading it would be churn that fixes nothing — and signalk-restricted-areas already passes ["20","22","24"], so a Node 20 caller is a live case rather than a hypothetical one.

Why the range stops at 11 instead of tracking npm@latest

npm 12 requires Node ^22.22.2 || ^24.15.0 || >=26.0.0, and npm install -g enforces an engine range with a hard failure, not a warning:

npm error notsup Not compatible with your version of node/npm: npm@12.0.2
npm error notsup Required: {"node":"^22.22.2 || ^24.15.0 || >=26.0.0"}
npm error notsup Actual:   {"npm":"10.9.4","node":"v22.22.0"}

A bare "22" resolves to the latest 22.x today and would be fine, but a caller pinning an earlier 22.x would have this step fail outright — trading a crash that only affects vitest users for one that affects every caller on that Node. npm 11 requires only >=22.9.0, installs cleanly there, and fixes the crash.

Within 11 the range floats (npm@^11), so patch and minor releases arrive without a change here.

I chose replacing npm over dropping Node 22 from the default matrix because the crash is npm's rather than Node's, and Node 22 is a runtime plugins are still installed on — dropping it would lose real coverage to work around a bug that a newer npm fixes outright.

Tested

Verified on Node 22 against a plugin that reproduces the crash, simulating exactly what the new step does:

  • Before: npm install fails with the edgesOut crash on both 22.22.0 (npm 10.9.4) and 22.23.2 (npm 10.9.8).
  • After npm install -g 'npm@^11' (resolves to 11.19.1): install succeeds (287 packages), npm run build succeeds, and the plugin's suite passes (52 tests across 6 files).
  • npm install -g 'npm@^11' exits 0 on both 22.22.0 and 22.23.2; npm install -g npm@latest exits 1 on 22.22.0 with the notsup error above.
  • Confirmed the 10.9.* case matches 10.9.4 and 10.9.8 while leaving 10.8.2, 10.10.0, 11.19.1 and 12.0.2 untouched.
  • plugin-ci.yml parses as valid YAML.

Not tested: a live run of this workflow on a GitHub runner, which needs the change to be on a branch the reusable workflow can be called from.

Summary

This PR pins npm 11.19.1 in both Node setup jobs of plugin-ci.yml when npm --version matches 10.9.*.

This avoids the npm Arborist crash during optional peer dependency resolution. It preserves older npm versions and Node 22 in the test matrix.

Dependency installation, build, 52 tests, and YAML parsing pass after the upgrade. A live GitHub Actions run is not performed.

@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: SignalK/signalk-server/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: a837dc1a-398e-4ddb-ac9e-c8b29030a8be

📥 Commits

Reviewing files that changed from the base of the PR and between 0c3fab7 and c2f9e14.

📒 Files selected for processing (1)
  • .github/workflows/plugin-ci.yml

Included review availability: Your plan provides up to 2 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The reusable plugin CI workflow adds npm version checks to the desktop and signalk-integration jobs. Each job installs npm 11.19.1 when it detects npm 10.9.x, then prints the resulting version.

Changes

npm version mitigation

Layer / File(s) Summary
CI npm version check and replacement
.github/workflows/plugin-ci.yml
The desktop and signalk-integration jobs replace npm 10.9.x with npm 11.19.1 and print the resulting npm version.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: joelkoz

Merge Risk: ⚪ Minimal · up to c2f9e

The npm workaround matches the workflow’s documented version policy, with no supported merge-blocking issue identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description clearly explains the npm 10.9.x failure, the workflow change, its scope, compatibility reasoning, and test results. It does not use the template headings exactly, but it fully covers t…
Title check ✅ Passed The title clearly and concisely describes the main change: replacing npm 10.9.x in plugin CI for Node 22 runners.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the fix label Sep 20, 2026
npm 10.9.x crashes while resolving an optional peer that is not being
installed:

  npm error Cannot read properties of null (reading 'edgesOut')
      at #loadPeerSet (@npmcli/arborist/lib/arborist/build-ideal-tree.js)

Any plugin depending on vitest reaches it through
@vitest/browser-playwright, so every Node 22 job fails at install before
a single test runs, whatever the pull request changed. It is upstream
npm/cli#9960 and #9787, both still open, and it is deterministic — the
install retry already in this workflow cannot clear it.

Both Node-setup jobs now replace that minor with npm 11. The version
test is an exact 10.9.* match rather than "older than 11": Node 20 ships
npm 10.8.2, which resolves the same tree cleanly, so upgrading it would
be churn that fixes nothing.

The range stops at 11 rather than tracking npm@latest. npm 12 requires
Node ^22.22.2, and `npm install -g` enforces an engine range with a hard
notsup failure rather than a warning, so @latest would fail this step
outright on a caller pinning an earlier 22.x — trading a crash that only
affects vitest users for one that affects everyone. npm 11 needs only
>=22.9.0 and fixes the crash. Within 11 the range floats, so patch
releases arrive without a change here.

Replacing npm rather than dropping Node 22 from the matrix keeps the job
testing a runtime plugins are still installed on: the crash is npm's,
not Node's.
@dirkwa
dirkwa force-pushed the fix-plugin-ci-npm10-peer-crash branch from 0c3fab7 to c2f9e14 Compare September 20, 2026 23:27
@dirkwa

dirkwa commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Ready for human review

@tkurki
tkurki merged commit dac6cc9 into SignalK:master Sep 21, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants