You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is in a workspace root. For the omitted dependencies I can see no clear picture: devDependencies from root, devDependencies from workspaces, prod dependencies from workspaces.
Expected Behavior
npm approve-scripts --allow-scripts-pending should not list already approved dependencies
npm approve-scripts --all should add all listed dependencies to allowScripts in package.json
Environment
npm: 11.17.0
Node.js: 22.21.1
OS Name: Linux
System Model Name: x86_64 GNU/Linux
npm config:
; "project" config from /home/wsl/git/redacted/.npmrcengine-strict = true
min-release-age = 3
; node bin location = /home/wsl/.local/share/fnm/node-versions/v22.21.1/installation/bin/node; node version = v22.21.1; npm local prefix = /home/wsl/git/sol24c-main; npm version = 11.17.0; cwd = /home/wsl/git/redacted; HOME = /home/wsl; Run `npm config ls -l` to show all defaults.
The scripts that get added by npm approve-scripts --all are all scripts from dependencies directly in code repo A's package.json.
The scripts that don't get added, are from deeper down the dependency tree.
I even tested updating a dependency I control, setting the allowScripts there, publishing, then installing the new version in repo A.
Upon doing npm ci again after the install(I double checked, it's set to the new version in package.json and package-lock.json), the output list remains identical. The scripts I've allowed for the dependency I control are still listed. And I can confirm these are not themselves also direct dependencies of repo A.
So it seems there's a discrepancy between the "allow" logic for a repo, and scripts and allow logic deeper down the dependency tree.
Even if I manually add an "allowScripts" list to repo A, with the correct entries, they will still show up in the output of npm ci.
I would assume that the intended behavior is that every code project has to explicitly approve every single script, regardless of depth in the dependency tree. The whole reason this functionality came to be was malicious dependencies. So, there's no trusting the allow list of a dependency further down the tree.
Thanks for the report, and thanks @KoenDG for confirming.
Could you share, sanitised (redact hostnames and tokens, but keep the URL shape):
The allowScripts and workspaces fields from your root package.json.
The resolved URLs for the affected and working packages, from the project root: node -e "const p=require('./package-lock.json').packages;const names=['esbuild','hana-client','mbt','sqlite3','xsd-schema-validator','protobufjs'];for(const [k,v] of Object.entries(p)){if(names.some(n=>k.includes(n)))console.log((v.resolved||'(no resolved)')+' <- '+k)}"
npm config get registry, and whether the lockfile points at a private registry or proxy.
Activity
KoenDG commentedon Jun 20, 2026
I am experiencing this as well.
Node version 22.20.0
NPM version 11.17.0
Let's say I have code repo A.
The scripts that get added by
npm approve-scripts --allare all scripts from dependencies directly in code repo A'spackage.json.The scripts that don't get added, are from deeper down the dependency tree.
I even tested updating a dependency I control, setting the allowScripts there, publishing, then installing the new version in repo A.
Upon doing
npm ciagain after the install(I double checked, it's set to the new version inpackage.jsonandpackage-lock.json), the output list remains identical. The scripts I've allowed for the dependency I control are still listed. And I can confirm these are not themselves also direct dependencies of repo A.So it seems there's a discrepancy between the "allow" logic for a repo, and scripts and allow logic deeper down the dependency tree.
Even if I manually add an "allowScripts" list to repo A, with the correct entries, they will still show up in the output of
npm ci.I would assume that the intended behavior is that every code project has to explicitly approve every single script, regardless of depth in the dependency tree. The whole reason this functionality came to be was malicious dependencies. So, there's no trusting the allow list of a dependency further down the tree.
JamieMagee commentedon Jun 22, 2026
Thanks for the report, and thanks @KoenDG for confirming.
Could you share, sanitised (redact hostnames and tokens, but keep the URL shape):
allowScriptsand workspaces fields from your rootpackage.json.node -e "const p=require('./package-lock.json').packages;const names=['esbuild','hana-client','mbt','sqlite3','xsd-schema-validator','protobufjs'];for(const [k,v] of Object.entries(p)){if(names.some(n=>k.includes(n)))console.log((v.resolved||'(no resolved)')+' <- '+k)}"npm config get registry, and whether the lockfile points at a private registry or proxy.KoenDG commentedon Jun 23, 2026
@JamieMagee
1/
allowScripts:
With that present, npm ci prints this:
No workspaces field defined.
2/
3/
Finding 235
"resolved": "https://and then also 235registry.npmjs.org/So, no private repo in lockfile, all registery.npmjs.org
fix(approve-scripts): approve deps with no resolved URL by name (#9606)
fix: write registry allowScripts keys under install-strategy=linked (#…