Skip to content

postinstall script in published 0.64.0 package breaks npm ci in consumer projects #725

Description

@bedrich-schindler

Description

@react-ui-org/react-ui@0.64.0 was published with a postinstall hook in
package.json:

"postinstall": "sh scripts/write-lockfile-hash.sh"

npm runs postinstall not only in the react-ui repo checkout, but also every
time the package is installed as a dependency. In a consumer project, the
script fails and aborts the consumer's entire install.

Steps to reproduce

  1. In any project, add "@react-ui-org/react-ui": "^0.64.0" as a dependency.
  2. Run npm ci (or npm install).

Actual behavior

The install fails:

npm error code 2
npm error path <project>/node_modules/@react-ui-org/react-ui
npm error command failed
npm error command sh -c sh scripts/write-lockfile-hash.sh
npm error sha256sum: package-lock.json: No such file or directory
npm error scripts/write-lockfile-hash.sh: 15: cannot create node_modules/.package-lock-hash: Directory nonexistent

Expected behavior

Installing the package as a dependency succeeds; the lockfile-hash mechanism
only runs inside the react-ui repo checkout.

Root cause

scripts/write-lockfile-hash.sh assumes it runs in a repo checkout: it hashes
package-lock.json into node_modules/.package-lock-hash (consumed by
scripts/docker/autoStartNode.sh to detect stale installs). Neither
assumption holds for an installed copy of the package:

  • npm never includes package-lock.json in a published tarball, so
    sha256sum package-lock.json fails.
  • The dependency's own node_modules/ directory does not exist, so the
    redirect to node_modules/.package-lock-hash fails.

With set -e, the script exits non-zero and npm treats it as a fatal install
error.

For reference, the postinstall in 0.63.0
(cp -n .env.dist .env && cp -n .env.playwright.dist .env.playwright || true)
ended with || true, so it could never fail for consumers. The unguarded
script is the 0.64.0 regression.

Suggested fix

In scripts/write-lockfile-hash.sh, right after the cd "$SCRIPT_DIR/.."
line, exit early when not in a repo checkout:

# Skip when running as an installed dependency: the published package
# contains no package-lock.json.
if [ ! -f package-lock.json ]; then
  exit 0
fi

The lockfile is a reliable marker of a repo checkout because npm never packs
it into a published tarball.

Removing the postinstall hook instead is not a good fix: the hash must be
rewritten whenever a developer runs npm ci manually in the devcontainer,
otherwise the stale-install detection in scripts/docker/autoStartNode.sh
silently breaks.

Verification

  1. In the repo, run npm ci and confirm node_modules/.package-lock-hash is
    still written with the sha256 of package-lock.json.
  2. Simulate a consumer install: npm pack, then in an empty temp directory
    run npm init -y && npm install <path-to-tarball> and confirm the install
    succeeds with no postinstall error.

Afterwards, release the fix as 0.64.1 (patch version bump).

Workarounds until fixed

  • Pin @react-ui-org/react-ui to 0.63.0, or
  • npm ci --ignore-scripts (skips all dependencies' lifecycle scripts).

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

Status
✅ Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions