npm retry behavior may cause duplicate package writes—how can this be prevented without disabling retries?
0 reputation · 27 Jul 2025, 19:53 UTC
0 reputation · 27 Jul 2025, 19:53 UTC
npm automatically retries failed network requests, and the default retry count varies between major versions, which can lead to repeated execution of install scripts after a partial write.
When a retry occurs, npm may re‑run the install script, causing duplicate entries in node_modules and an inconsistent package‑lock.json, especially if the script performs side‑effects before the network failure is resolved.
Since the CLI lacks a flag to disable retries entirely, developers must rely on external wrappers or environment variables, raising uncertainty about how to safely limit retries without corrupting the lockfile.
Is there a configuration option to set the retry count to zero while preserving lockfile integrity? Can the retry mechanism be made idempotent for install scripts? Does npm provide a way to isolate retries from side‑effects in package scripts?
35275 reputation · 28 Jul 2025, 07:11 UTC
No. npm can stop retrying failed registry fetches by setting fetch-retries to 0, but that does not make install scripts idempotent, isolate their side effects from retries, or repair an already inconsistent package-lock.json. Duplicate writes usually come from re-running the install after a partial failure or from non-idempotent lifecycle scripts, not from npm retrying a single fetch.
When a registry tarball fetch fails, npm retries the fetch itself. It does not normally re-run preinstall, install, or postinstall on every retry. If you see duplicate entries or repeated side effects, the more probable causes are:
npm install after the first attempt fails partway through.node_modules and package-lock.json out of sync.fetch-retries, fetch-retry-mintimeout, fetch-retry-maxtimeout, and fetch-retry-factor. Defaults vary by npm major version.npm ci requires package.json and package-lock.json to be synchronized; it fails rather than repairing a drifted lockfile.fetch-retries to 0 makes the first failed fetch fail the install immediately. It increases fail-fast behavior but does not fix existing corruption.npm config get fetch-retriesnpm install --fetch-retries 0preinstall, install, and postinstall in package.json. Guard file writes with a sentinel file or existence check so the script is idempotent.npm ci from a committed lockfile. If the lockfile is corrupted, regenerate it from a known-good commit rather than editing it by hand.Do the duplicates appear after a single npm install completes, or only when something re-runs the command after a failure? This determines whether to adjust fetch-retries or fix the external wrapper and lifecycle scripts.
This answer assumes a recent npm major version (npm 6 or later). Config names and default retry counts can differ in older versions; verify with npm config get fetch-retries. It is not confirmed that npm re-runs lifecycle scripts on every fetch retry; treat that as unverified and check your own install output if the problem persists.
npm config get fetch-retries before and after npm install --fetch-retries 0 to confirm the flag applies.git diff -- package-lock.json and check whether script-generated files appear more than once.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.