Repository navigation
Description
Self-service
- I'd be willing to implement a fix
Describe the bug
yarn upgrade-interactive silently ignores errors encountered while querying a registry for available package versions.
For example, when a dependency is hosted on a private npm registry and the registry responds with 403 Forbidden, yarn install correctly reports the error, but yarn upgrade-interactive silently behaves as if there were no upgrade available.
This makes it impossible to distinguish between:
- the package having no available upgrade, and
- Yarn being unable to determine whether an upgrade is available.
To reproduce
- Configure a dependency to use a private npm registry.
- Make the registry return
403 Forbiddenwhen Yarn queries package metadata (for example, due to missing/invalid credentials). - Run:
Yarn reports the registry error, e.g.
yarn install403 Forbidden. - Run:
The package is silently omitted from the list of upgrade candidates. No error or warning is displayed.
yarn upgrade-interactive
Expected behavior
yarn upgrade-interactive should indicate that it was unable to check the package.
It doesn't necessarily need to abort the entire interactive command — other packages could still be displayed — but a registry error should not be indistinguishable from "no update is available."
For example, it could display a warning such as:
Warning: failed to check @example/private-package for updates: HTTP 403 Forbidden
or otherwise mark the package as unavailable to check.
Actual behavior
The registry error is silently discarded and the package is omitted from the upgrade suggestions.
Environment
System:
OS: Linux 7.0 Ubuntu 24.04.4 LTS 24.04.4 LTS (Noble Numbat)
CPU: (8) x64 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
Binaries:
Node: 20.20.1 - /tmp/xfs-b142f623/node
Yarn: 4.12.0 - /tmp/xfs-b142f623/yarn
npm: 10.8.2 - /home/juho/.nvm/versions/node/v20.20.1/bin/npmAdditional context
The result of running yarn install displays errors:
But yarn upgrade-interactive does not:
The current implementation contains:
const [resolution, latest] = await Promise.all([
fetchUpdatedDescriptor(descriptor, descriptor.range, referenceRange).catch(() => null),
fetchUpdatedDescriptor(descriptor, descriptor.range, `latest`).catch(() => null),
]);The catch(() => null) means that registry errors are converted to null.
Later, packages with no non-empty suggestions are removed:
if (suggestions.filter(suggestion => suggestion.label !== ``).length <= 1)
return null;Therefore, an HTTP error becomes indistinguishable from a package for which no upgrade is available.
Source:
Activity