Skip to content

The allowScripts allowlist is version-pinned and has silently gone stale #4374

Description

@Astro-Han

What happened

The root package.json declares:

"allowScripts": {
  "esbuild@0.27.7": true,
  "@jackwener/opencli@1.8.4": true,
  "node-pty@1.2.0-beta.15": true
}

npm matches these by exact name@version. Our lockfile installs esbuild@0.28.2 and @jackwener/opencli@1.8.6, so two of the three entries match nothing and only the node-pty entry is still live.

Because the field is present, npm denies by default, so a clean npm ci from the repo root silently skips eight packages' install scripts and still exits 0:

npm warn install-scripts 8 packages have install scripts not yet covered by allowScripts:
npm warn install-scripts   @astryxdesign/cli@0.4.5 (postinstall: node scripts/postinstall.mjs)
npm warn install-scripts   @astryxdesign/core@0.5.0 (postinstall: node scripts/postinstall.mjs)
npm warn install-scripts   @jackwener/opencli@1.8.6 (postinstall: node scripts/postinstall.js || true; node scripts/fetch-adapters.js || true)
npm warn install-scripts   electron-winstaller@5.4.0 (install: node ./script/select-7z-arch.js)
npm warn install-scripts   esbuild@0.28.2 (postinstall: node install.js)
npm warn install-scripts   fsevents@2.3.3 (install: (install scripts present))
npm warn install-scripts   fsevents@2.3.2 (install: (install scripts present))
npm warn install-scripts   protobufjs@7.6.5 (postinstall: node scripts/postinstall)

The defect is not any individual skip. It is that a version-pinned allowlist goes stale on every dependency bump, silently, and we can no longer tell "reviewed and allowed" apart from "no longer matches anything". We chose deny-by-default deliberately; right now that choice is not being enforced the way the file suggests.

How to reproduce

Run npm ci from the repo root on a clean checkout and read the install-scripts warnings.

Environment

macOS arm64, Node 24, npm 11.19.0.

Additional context

This splits into a part that is confirmed and a part that still needs investigation. The two can land as one change or two — whichever the person picking it up prefers.

Confirmed, and safe to act on:

  • The allowlist has rotted and will rot again on the next bump of any listed package.
  • It needs a guard. Please check first whether npm 11 supports anything other than exact name@version keys; if it does not, a check script is the only way to keep the list honest. There is an existing family of check:* scripts in the root package.json, wired through .github/workflows/ci.yml — extending that seam is preferable to inventing a new mechanism.

Still open, and the reason I have not proposed a specific list:

  • Whether skipping each of the eight actually degrades anything on macOS arm64, Linux x64 or Windows x64. Please verify rather than assume. For example esbuild ships its binary through the @esbuild/<platform> optional dependency, which may make its install.js redundant; the two @astryxdesign postinstalls appeared to only print a "Next step: run npx @astryxdesign/cli init" notice; electron-winstaller matters only on the Windows packaging lane. Recording the evidence per package matters more than the final verdict, because the next person will otherwise have to redo it.

Deny-by-default should stay. The goal is an honest list, not allowing all eight — where a skip is harmless, saying so explicitly is a better outcome than adding it.

One thing that is out of scope: npm mentions an .npmrc allow-scripts setting in its first warning line. This repository has no .npmrc; that setting comes from the individual contributor's own ~/.npmrc and is unrelated.

Separately, and also out of scope: I have seen worktrees where node_modules/electron/ exists but dist/ and path.txt do not, and where the patches/ entry for @ai-sdk/provider-utils was not applied either. That points at the root postinstall chain not running at all, which is a different failure — Electron's binary is fetched by scripts/install-electron-with-retry.mjs, not by any allowlisted dependency script. I could not determine the cause and am not filing it until I can.

Analysis produced with Claude Code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions