Run npm install --allow-scripts=sharp inside a repo on npm 12 and it stops dead: npm error code EALLOWSCRIPTS, followed by --allow-scripts is not allowed in project-scoped installs. The flag npm 11 practically told you to reach for is forbidden the moment a package.json is in the room. That rejection is deliberate. The trap is that the same error also lands on a plain npm install where you never typed the flag, because npm feeds your own config back into itself and then refuses it.
TL;DR: There are two ways to hitEALLOWSCRIPTS. If you passed--allow-scriptsinside a project, that is by design: commit the allowlist topackage.jsonwithnpm approve-scripts. If you did not pass it and the failing install pulls a git dependency, you are on npm/cli issue #9783, where npm forwards your user.npmrcvalue as an environment variable into an inner project-scoped install and rejects it. The workaround is to keepallow-scriptsout of user or global.npmrcand pass it only on the specific global install that needs it.
What throws EALLOWSCRIPTS in npm 12?
npm 12 flipped install scripts off by default. The preinstall, install, postinstall, and prepare lifecycle scripts from your dependencies no longer run unless the package is listed in an allowScripts allowlist. The npm team published the breaking changes on 2026-06-09, and the current release line is npm 12.0.1 on Node 26. This is npm catching up to the reality that install scripts are where a compromised package actually executes, the same fast-publish window that dependency cooldowns close from the release-timing side. If you are still on the warning phase and have not written your allowlist yet, the npm v12 allowScripts migration walks the full window; this piece is about the one error string developers are Googling verbatim once the migration bites.
The exact output, per npm/cli issue #9783, is three lines:
npm error code EALLOWSCRIPTS
npm error --allow-scripts is not allowed in project-scoped installs.
npm error Add the entries to the "allowScripts" field in package.json, or to .npmrc, instead.
It reproduces on npm 11.17.0 and 12.0.1 under Node 26.5.0. The old habit of typing --allow-scripts and moving on now hits a wall the instant you are inside a repo.
Why npm forbids the flag inside a project
Two different people hit this, and only one of them did something wrong.
The first typed npm install --allow-scripts=sharp inside a project, expecting the flag to behave the way it did in npm 11. npm 12 draws a boundary here on purpose. A transient context with no package.json to write to, such as npm install -g or npx, gets the flag. A project gets a committed, reviewable allowlist instead. That is the correct call. An install-time flag leaves no audit trail, and a supply-chain decision that lives only in a shell history is a decision nobody on your team can review later. A committed allowlist is an auditable artifact, the same instinct behind shipping an SBOM with Syft rather than trusting a build to remember what it pulled.
The npm v12 install-scripts docs spell out where the flag belongs: global and one-off contexts like npm install -g --allow-scripts=canvas,sharp, or persisted with npm config set. Inside a project, npm approve-scripts writes the allowlist directly into package.json. Run that command with --global instead and it fails with EGLOBAL. The two errors bracket the same rule from opposite sides: the allowlist belongs in the project file, the flag belongs to global contexts, and each side rejects the other.
The confused deputy: npm forwards your config, then rejects it
The second person never passed the flag. They followed npm's own documented advice for global tools, npm config set allow-scripts=canvas,sharp --location=user, and later ran a plain npm install on a project that happens to pull a git dependency. That install fails with the same EALLOWSCRIPTS message telling them to put the setting in .npmrc, where it already is.
Here is the mechanism, straight from issue #9783. When npm prepares a git dependency, it spawns an inner install to build that dependency, and it forwards the outer config down as npm_config_* environment variables. npm's resolveAllowScripts logic treats a value arriving through the environment layer identically to a command-line flag. So in the inner project-scoped install, it sees what looks like --allow-scripts passed on the CLI, and it rejects it, even though the user set the value in user .npmrc exactly as npm recommends and never touched the flag.
That makes npm a confused deputy against its own config. The layer a value came from is load-bearing here. npm's config precedence runs CLI flag, then environment, then project .npmrc, then user .npmrc. The value allow-scripts=canvas is legal in the user layer and illegal in the CLI and env layers for a project install. npm collapses the env layer into the CLI layer during git-dep prep, so a legal user-level setting gets judged as an illegal flag.
You could argue npm is simply being strict, and strict is the right posture for anything that runs arbitrary code at install time. Fair, except it is being strict about a value it injected itself. The message compounds the confusion: it tells you to move the entry to .npmrc, the entry is already in .npmrc, and the setting in .npmrc is precisely what npm re-injected as an env var and then refused. The fix the error suggests is the thing you already did, which is exactly why the string is being searched.
Two paths, one error
Before you fix anything, figure out which error you have. The distinguishing signal is whether you typed the flag and whether the failing install resolves a git dependency.
You see EALLOWSCRIPTS because... | You did | The fix |
|---|---|---|
You passed --allow-scripts in a project | npm i --allow-scripts=sharp in a repo | Add the dep to allowScripts in package.json via npm approve-scripts, or set it in project .npmrc |
| npm forwarded your global config into a git-dep prep (issue #9783) | npm config set allow-scripts=... --location=user, then a plain npm install | Keep allow-scripts out of user or global .npmrc; pass it only on the specific global install that needs it |
The bug path flows like this:
If your package.json has no git or GitHub dependency and the install still fails, you are almost certainly on the by-design path and passed the flag somewhere, including a CI wrapper script you inherited.
How to clear EALLOWSCRIPTS this week
Work the list in order. Each step ties to a specific from above.
- Confirm your npm version. Run
npm --version. If it reports 12.0.1 (or 11.17.0 with the new behavior), the default is off and this error is live. On older npm you will see a warning, notEALLOWSCRIPTS. - By-design path, project scope. Stop passing
--allow-scriptsinside the repo. Runnpm approve-scripts --allow-scripts-pendingto list every package requesting a script, thennpm approve-scripts <pkg>for the ones you trust andnpm deny-scripts <pkg>for the rest. This writes a reviewableallowScriptsblock intopackage.json, which is the artifact you want in version control anyway. Commit it. - Bug path, issue #9783. Remove
allow-scriptsfrom user and global.npmrc. Check withnpm config get allow-scripts --location=userand clear it withnpm config delete allow-scripts --location=user. Pass the setting inline only on the global install that needs it:npm install -g <pkg> --allow-scripts=<pkg>. That keeps it from leaking into any project's git-dependency preparation. - CI hardening. If a pipeline exports
allow-scriptsas an environment variable or drops it into a shared.npmrc, expect this failure the first time a build resolves a git dependency. Scope the setting to the exact global-install step, never the whole job. Grep your runner config forallow_scripts,allow-scripts, andnpm_config_allow_scriptsand move each one to the step that owns it. - Make
package.jsonthe source of truth. Treat theallowScriptsfield as the single place project script policy lives. Keep global-tool exceptions out of persistent config, and do not trust an error that tells you to do the thing you already did. Check which config layer a value came from, not just its value.
npm 12's safe default is the right one. The flag-versus-field split only leaks because npm crosses its own trust boundary through environment inheritance during git-dep prep. Until #9783 is patched, the durable fix is keeping your allowlist committed and your global exceptions ephemeral.
Sources
- npm/cli issue #9783, allow-scripts from
.npmrcfails git-dependency prep with EALLOWSCRIPTS - npm Docs, npm-install-scripts (v12)
- GitHub Changelog, Upcoming breaking changes for npm v12 (2026-06-09)
- npm Docs, npm-approve-scripts

Comments
Be the first to comment.