From e069068ce73f5d211a56ea805f848c3c275d1247 Mon Sep 17 00:00:00 2001 From: abhishek Date: Wed, 9 Sep 2026 18:09:11 +0530 Subject: [PATCH] repair the lock file the leaflet install broke MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The deploy died on `npm ci` with "Missing: @emnapi/core@1.11.3 from lock file". Nothing was wrong with the code — the lock really was incomplete, and the Dockerfile was right to refuse it. I broke it. Adding leaflet ran `npm install` under npm 11.6.2; the builder is node:22-alpine, which ships npm 10.9.8. npm 11 prunes optional platform packages that npm 10 still validates, and it dropped `@emnapi/core` and `@emnapi/runtime` — transitive optional deps of `@tailwindcss/oxide-wasm32-wasi`. Both were present in the lock at b760c1a and absent from 34bf798 onward. Regenerated with `npx npm@10.9.8 install --package-lock-only`, which restores both entries and keeps leaflet 1.9.4 / @types/leaflet 1.9.22. Verified by running the builder's exact command in a scratch directory: the old lock reproduces the failure, the new one gives "added 212 packages" under npm 10.9.8 AND under npm 11.6.2 — so it holds whichever npm the image ships. No Dockerfile change was needed for that. The Dockerfile comment did need one. It said the fix was "`npm install` locally and COMMIT the updated package-lock.json", which is exactly the step that caused this. It now says to prove the lock against npm 10.9.8 in a scratch directory before pushing, and how to regenerate it if it fails. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01JYEsb8PNZ19G9R8gUjTU7n --- Dockerfile | 27 ++++++++++++++++++++++++--- package-lock.json | 46 ++++++++++++++++++++++------------------------ 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/Dockerfile b/Dockerfile index f954d43..94c5601 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,9 +13,30 @@ COPY package*.json ./ # never pinned, so the deployed bundle is built from dependencies nobody chose # and nobody can reproduce. # -# When this line fails, the fix is `npm install` locally and COMMIT the updated -# package-lock.json. The build should not paper over a lock file that is out of -# date; it should say so. +# When this line fails, the fix is to update package-lock.json locally and +# COMMIT it. The build should not paper over a lock file that is out of date; +# it should say so. +# +# ── But `npm install` alone is how the lock got broken once ───────────────── +# +# This image is node:22-alpine, which ships npm 10.9.8. A developer on npm 11 +# running `npm install` rewrites the lock in a shape npm 10 rejects: npm 11 +# prunes optional platform packages that npm 10 still validates. Adding leaflet +# on npm 11.6.2 dropped `@emnapi/core` and `@emnapi/runtime` — transitive +# optional deps of `@tailwindcss/oxide-wasm32-wasi` — and the next deploy died +# here with "Missing: @emnapi/core@1.11.3 from lock file". Nothing was wrong +# with the code; the lock was genuinely incomplete and this line was right to +# refuse it. +# +# So after changing dependencies, prove the lock against THIS npm before +# pushing, in a scratch directory so node_modules is not disturbed: +# +# mkdir /tmp/lockcheck && cp package.json package-lock.json /tmp/lockcheck/ +# cd /tmp/lockcheck && npx npm@10.9.8 ci +# +# and if it fails, regenerate with the same version: +# +# npx npm@10.9.8 install --package-lock-only RUN npm ci --no-audit --no-fund COPY . . diff --git a/package-lock.json b/package-lock.json index f92d0df..73bb505 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,7 +81,6 @@ "integrity": "sha512-rbGaoAGZq1QImY2VWeWQNAh1ZqQa/KLWnmoOdy13lSjzMcAPDS6WrVv9fZfsNDx+DIG2oySLtMikwZk5WFl1Uw==", "hasInstallScript": true, "license": "MIT", - "peer": true, "dependencies": { "intl-messageformat": "^11.2.9" }, @@ -122,7 +121,6 @@ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", @@ -695,17 +693,6 @@ "node": ">=6.9.0" } }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz", - "integrity": "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.28.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", @@ -1534,7 +1521,6 @@ "resolved": "https://registry.npmjs.org/@stylexjs/stylex/-/stylex-0.19.0.tgz", "integrity": "sha512-CnUFp7YMaDLDeemsWOfJgoC/gKM5P/yBNMcpJaE6ChJmXr7s0DJwSeGTTlHJcqqwN9OW1qGtmARWLFhGZN1pTA==", "license": "MIT", - "peer": true, "dependencies": { "css-mediaquery": "^0.1.2", "invariant": "^2.2.4", @@ -1764,6 +1750,27 @@ "node": ">=14.0.0" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.11.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { "version": "1.2.2", "dev": true, @@ -2015,7 +2022,6 @@ "integrity": "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~8.3.0" } @@ -2026,7 +2032,6 @@ "integrity": "sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -2463,7 +2468,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.11.12", "caniuse-lite": "^1.0.30001809", @@ -3681,7 +3685,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -3691,7 +3694,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -3711,7 +3713,6 @@ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.3.0.tgz", "integrity": "sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==", "license": "MIT", - "peer": true, "dependencies": { "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.4.0" @@ -3829,8 +3830,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/redux-thunk": { "version": "3.1.0", @@ -4052,7 +4052,6 @@ "integrity": "sha512-FDf4L4sYzKtzWYhU/Xm0AQFdTjdIxNo9ElTf2mxXM6k8YMHXzYUe4yODVaXP4V9uMFbVg8c0qyBccK2OOxb45Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "~0.28.0" }, @@ -4176,7 +4175,6 @@ "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.5",