npm deprecate returns E422 Unprocessable Entity although the registry applies the deprecation
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 10.1k
- Forks
- 4.7k
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 19
Description
Is there an existing issue for this?
I searched and found two prior reports that describe the same symptom, both now closed:
- #2581 (npm v6/v7/v8 era, closed as v6 no longer active)
- #7982 (npm 10.9.0, self-closed by the reporter within ~90 minutes on the assumption it was an already-fixed old bug)
Re-filing because the behavior is still present on current npm versions and neither prior issue was actually triaged to a fix.
This issue exists in the latest npm version
Reproduced on npm 10.9.4 (node 22.22.0) and on npm 12.0.1 (run via npx).
Current Behavior
npm deprecate returns code E422 / 422 Unprocessable Entity - PUT https://registry.npmjs.org/<pkg> and exits non-zero, but the registry actually applies the deprecation write. Reading the packument back afterward shows the deprecated field correctly set on every targeted version. So the command reports failure for an operation that in fact succeeded.
This happens with both the range form and the single-version form of the command.
Verbatim error output:
npm error code E422
npm error 422 Unprocessable Entity - PUT https://registry.npmjs.org/<pkg>
The debug log shows the usual read-modify-write flow: a GET .../<pkg>?write=true returns 200, then the PUT .../<pkg> returns 422. Despite the 422 on the PUT, the deprecation is persisted (confirmed by a subsequent packument read).
Expected Behavior
When the registry applies the deprecation, npm deprecate should exit 0 and report success. If the PUT genuinely fails, the deprecation should not be persisted. The current state (client reports 422 failure, registry persists the write) is inconsistent and misleads automation that checks the exit code.
Steps To Reproduce
Using any package the reporter owns:
- Deprecate a range of versions:
Observenpm deprecate "<pkg>@<=X.Y.Z" "<notice text>"code E422/422 Unprocessable Entity - PUT https://registry.npmjs.org/<pkg>and a non-zero exit. - Deprecate a single version:
Samenpm deprecate <pkg>@X.Y.Z "<notice text>"E422result. - Read the packument back (
npm view <pkg> versions --json/ fetchhttps://registry.npmjs.org/<pkg>) and confirm thedeprecatedfield is set on every targeted version despite the reported error.
Reproduced across two npm/node combinations:
- npm 10.9.4, node 22.22.0
- npm 12.0.1 (via npx)
Environment
- npm: 10.9.4 and 12.0.1
- Node: 22.22.0
- Registry: registry.npmjs.org
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the npm deprecate command and its read-modify-write request flow, then reproduce the PUT response against registry.npmjs.org using the versions and commands in the report. Determine why a persisted deprecation produces E422, and add coverage for both range and single-version forms so the exit status reflects the observed registry result.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- backend-api-design, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100