Skip to content

feat(outdated): warn about packages skipped due to registry errors#34974

Merged
bartlomieju merged 2 commits into
mainfrom
feat/outdated-private-registry-warnings
Jun 7, 2026
Merged

feat(outdated): warn about packages skipped due to registry errors#34974
bartlomieju merged 2 commits into
mainfrom
feat/outdated-private-registry-warnings

Conversation

@bartlomieju

Copy link
Copy Markdown
Member

When deno outdated could not fetch a package's metadata, for example
because it lives on an unreachable or unauthorized private registry, the
package was silently dropped from the table. There was no way to tell that
apart from the package being up to date, which is confusing for enterprise
users who depend on private registries.

The package metadata fetch errors were collapsed into None before they
reached the caller, so the skip site had nothing to report. This threads
the failure reason (and the registry it came from) through the npm and jsr
fetch resolvers, and has deno outdated print a warning telling the user
how many packages could not be checked. Running with --log-level=debug
additionally lists each affected package, its registry, and the underlying
reason.

Closes #32179

Previously, when `deno outdated` could not fetch a package's metadata
(e.g. an unreachable or unauthorized private registry), the package was
silently dropped from the table, indistinguishable from being up to date.

The package info fetch errors are now threaded through instead of being
collapsed into `None`, and `deno outdated` prints a warning listing how
many packages could not be checked. With `--log-level=debug`, it lists
each package, its registry, and the failure reason.

Closes #32179
@bartlomieju

Copy link
Copy Markdown
Member Author

Review

Clean, well-targeted change. The info_by_name caches now store Result<Arc<Info>, Arc<PackageInfoLoadError>>, package_info() stays as a thin .ok() wrapper over the new package_info_with_reason(), and the error rides up on PackageLatestVersion::fetch_error to print_outdated. Good test coverage, and nice that the skip is recorded before the let Some(resolved) = … else { continue } guard so it still surfaces when the current version can't resolve. Also resolves the stale todo(dsherret)/.ok() comments rather than leaving them.

A few things worth addressing:

  1. registry_url means different things for npm vs jsr. For npm it's the per-package metadata URL (get_package_urlhttp://localhost:9/@acme%2fwidget, as warning_verbose.out shows), but for jsr it's the registry root (jsr_url()). So the field name is misleading on the npm side and the two sources aren't consistent. Either use the npm registry base URL, or rename the field to something like source_url to reflect what's actually stored.

  2. deno outdated --update doesn't surface skips. The warning lives only in the listing path (print_outdated); the update path silently won't update unfetchable packages, which is the same blind spot for --update users. Probably a follow-up, but worth noting.

  3. Minor: get_package_url is computed twice on the npm cache-miss path (once for registry_url, once inside fetch_package_info) — could compute once and reuse.

Non-blocking notes: transient network errors get memoized as hard errors for the resolver's lifetime (matches the prior None-caching behavior, resolver is per-invocation, so not a regression); and reason: String flattens the error type early, which is fine for a diagnostic-only field.

No correctness concerns — logic is sound and the test uses the discard port for a deterministic failure. The main thing I'd resolve before merge is #1.

- npm now stores the registry base URL (matching jsr) instead of the
  per-package metadata URL, and avoids computing get_package_url twice.
- Extract collect_skipped/SkippedPackages and surface the skipped-packages
  warning in the `outdated --update` path too, not just the listing path.

@bartlomieju bartlomieju left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: LGTM ✅

The second commit (2b813c0) resolves all three points from the earlier review:

  1. Consistent registry_url — npm now stores the registry base URL via npmrc.get_registry_url(name) (e.g. http://localhost:9/), matching jsr's jsr_url(). warning_verbose.out updated accordingly.
  2. Update path warns tooprint_skipped_warning is now called in update(), with collect_skipped running before any continue.
  3. No double get_package_url — the error path uses get_registry_url; get_package_url is computed once inside fetch_package_info.

Other things I verified:

  • DepKind derives Ord and has scheme(), so the BTreeMap<(DepKind, StackString), _> key is valid.
  • The filter (deno outdated --update <filter>) is applied upstream in DepManager::from_workspace[_dir], so the skip warning only covers in-scope packages — no noise from filtered-out deps.
  • collect_skipped runs before the let Some(resolved) = … else { continue } guard, so skips still surface when the current version can't resolve.
  • Errors from the earlier req_to_nv fetch are cached in info_by_name and reused by the latest-version computation (one fetch, error preserved).
  • The test uses the discard port (localhost:9) for a deterministic, fast connection-refused failure.

Non-blocking: transient network errors get memoized as hard errors for the resolver's lifetime, but the resolver is per-invocation so it's not a regression; and reason: String flattens the error early, which is fine for a diagnostic-only field.

Clean, well-targeted, good test coverage. Just needs CI to go green before merge.

@bartlomieju
bartlomieju enabled auto-merge (squash) June 7, 2026 09:58
@bartlomieju
bartlomieju merged commit acc328f into main Jun 7, 2026
268 of 270 checks passed
@bartlomieju
bartlomieju deleted the feat/outdated-private-registry-warnings branch June 7, 2026 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve error messaging for private npm registries in deno outdated

1 participant