nodejs/node · error · Error
You cannot publish over the previously published versions: $
Error message
You cannot publish over the previously published versions: ${manifest.version}. What it means
Thrown by `npm publish` when the package version being published already exists in the registry's version list and `--force` is not set. The registry rejects republishing an immutable version, so npm fails fast before the network call with a clear message.
Source
Thrown at deps/npm/lib/commands/publish.js:176
)
}
if (noCreds) {
const msg = `This command requires you to be logged in to ${outputRegistry}`
if (dryRun) {
log.warn(this.#command, `${msg} (dry-run)`)
} else {
throw Object.assign(new Error(msg), { code: 'ENEEDAUTH' })
}
}
if (!force) {
const { highestVersion, versions } = await this.#registryVersions(resolved, registry)
/* eslint-disable-next-line max-len */
const highestVersionIsGreater = !!highestVersion && semver.gte(highestVersion, manifest.version)
if (versions.includes(manifest.version)) {
throw new Error(`You cannot publish over the previously published versions: ${manifest.version}.`)
}
if (highestVersionIsGreater && isDefaultTag) {
throw new Error(`Cannot implicitly apply the "latest" tag because previously published version ${highestVersion} is higher than the new version ${manifest.version}. You must specify a tag using --tag.`)
}
}
const access = opts.access === null ? 'default' : opts.access
const verb = this.isStage ? 'Staging' : 'Publishing'
let msg = `${verb} to ${outputRegistry} with tag ${defaultTag} and ${access} access`
if (dryRun) {
msg = `${msg} (dry-run)`
}
log.notice('', msg)
let stageId
if (!dryRun) {View on GitHub (pinned to 1b2de5e052)
Solutions
- Bump the version in package.json (`npm version patch|minor|major`) before publishing.
- If the prior publish genuinely failed and left no artifact, unpublish the version first (within the time window), then republish.
- Use a different registry or scope, or `--force` only if you understand the registry will still reject immutable versions.
- Verify you are targeting the intended registry (`--registry`) and not accidentally republishing to the public one.
Example fix
// before npm publish // 1.2.3 already on registry // after npm version patch && npm publish
Defensive patterns
Strategy: validation
Validate before calling
const semver = require('semver')
async function assertVersion unpublished(pkgName, version, registry) {
const res = await fetch(`${registry}/${pkgName}`, { headers: { accept: 'application/json' } })
const data = await res.json()
const published = Object.keys(data.versions || {})
if (published.includes(version)) {
throw new Error(`${pkgName}@${version} is already published; bump the version.`)
}
} Try / catch
try {
await npmPublish()
} catch (e) {
if (/cannot publish over the previously published/i.test(e.message)) {
await run('npm version patch')
return npmPublish()
}
throw e
} Prevention
- Bump the version automatically in CI after every successful publish.
- Run `npm view <pkg> versions --json` in a pre-publish check.
- Make publish jobs idempotent or guarded so re-runs do not republish.
When it happens
Trigger: Running `npm publish` for a version that `#registryVersions` already returned in `versions` (i.e. the registry's `/<pkg>` document lists `manifest.version`), with `force` disabled.
Common situations: Re-running a CI publish job after it partially succeeded; forgetting to bump `version` in package.json after a successful publish; local publish against a local/cached registry that already holds the version.
Related errors
- You must specify a tag using --tag when publishing a prerele
- Cannot implicitly apply the "latest" tag because previously
- Could not read package.json from tarball
- invalid version range: ${spec}
- ${tag} is not a dist-tag on ${spec.name}
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/a4a50e7516ab928e.
Report an issue: GitHub.