npm / npm/cli

npm deprecate returns E422 Unprocessable Entity although the registry applies the deprecation

Open
#9,795 0 comments 1 reaction 0 assignees View on GitHub

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:

  1. Deprecate a range of versions:
    npm deprecate "<pkg>@<=X.Y.Z" "<notice text>"
    
    Observe code E422 / 422 Unprocessable Entity - PUT https://registry.npmjs.org/<pkg> and a non-zero exit.
  2. Deprecate a single version:
    npm deprecate <pkg>@X.Y.Z "<notice text>"
    
    Same E422 result.
  3. Read the packument back (npm view <pkg> versions --json / fetch https://registry.npmjs.org/<pkg>) and confirm the deprecated field 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.