Yarn Berry enableScripts:false Skips postinstall - Fix Missing Native Setup in CI
Yarn Berry can disable package build scripts globally with enableScripts: false (or per-package) for supply-chain safety. Like npm’s ignore-scripts, that leaves packages needing a postinstall - native addons, binary downloads - incomplete, so they fail at runtime.
What this error means
Install succeeds under Yarn Berry, but a package that depends on a build/postinstall step is missing its native artifact and crashes at runtime. Inspecting .yarnrc.yml shows enableScripts: false (or the package excluded from enableScripts/dependenciesMeta).
# .yarnrc.yml: enableScripts: false
# later at runtime:
Error: Could not load the native binding
'/app/.yarn/unplugged/some-native.../build/Release/addon.node'
# the build script that produces addon.node was skippedDiagnose it: reproduce the CI install locally
Install failures are usually environment drift rather than a broken lockfile: a different package-manager major, a different Node version, or a cache that is being restored from a run with different inputs. Reproduce the CI conditions before changing the lockfile, because regenerating it hides the real cause.
# match the runner exactly, then install from a clean slate
node --version && npm --version
rm -rf node_modules
npm ci --foreground-scripts
# if that succeeds locally but fails in CI, the difference is the cache
# or the package-manager version, not your lockfileCommon causes
Build scripts disabled globally
enableScripts: false turns off all package build scripts. Packages that legitimately compile natives or fetch binaries in their build step are left incomplete.
A specific package’s scripts not enabled
With scripts disabled by default, a package whose build is not explicitly allowed (via dependenciesMeta.<pkg>.built) never runs its build.
How to fix it
Allow builds for the packages that need them
Re-enable the build for the specific native packages, or rebuild them.
# .yarnrc.yml - keep scripts off but allow specific builds
# (or set per-package in package.json dependenciesMeta)
"dependenciesMeta": {
"some-native": { "built": true }
}
# then reinstall so the build runs
yarn installAudit which packages need a build
- Identify dependencies that compile natives or download binaries in postinstall.
- Allow their builds explicitly rather than disabling the safety setting wholesale.
- Confirm the native artifact exists after install before relying on it.
Verify the fix survives a cold cache
A green run immediately after a fix often proves nothing, because it restored a cache written before the change. Force a cold install once to confirm the fix is real.
# temporarily bust the cache key to prove the fix on a cold runner
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: package-lock.json
# then bump this suffix once, run, and remove it
# key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}-v2How to prevent it
- Allow builds narrowly for trusted native packages.
- Inventory postinstall-dependent deps before disabling scripts.
- Verify native artifacts exist after a scripts-disabled install.