fix(config): surface invalid "exports" map in linked/workspace packages#34473
Conversation
When a linked (or workspace member) JSR package had an invalid "exports" map (e.g. a key like "types" instead of "./types"), the package was silently dropped during resolution via `resolver_jsr_pkgs` (`.ok()?`), causing Deno to fall back to fetching it from the JSR registry. This produced a confusing "JSR package not found" error with no indication of the real problem — not even in the internal logs. Add an `InvalidExports` workspace diagnostic that validates the "exports" map for every config file (members and links) and reports exactly what is wrong, so the user gets an actionable warning instead of silence. Closes denoland/orchid#272 Co-Authored-By: Divy Srivastava <[email protected]>
exports map|
CI note: the only failing check is `test node_compat (3/3) debug` on linux-aarch64 / macos-aarch64 / macos-x86_64, which fails on `node_compat::internet::test-dns-any.js` — a live-DNS `ANY` query test in the `internet::` category. The same shard passes on linux-x86_64 and the Windows runners, so this is a network flake unrelated to this change (which only adds a workspace config diagnostic and cannot affect that test — node_compat runs with `--quiet`, which suppresses the new warning anyway). A re-run of the failed shard should clear it. |
bartlomieju
left a comment
There was a problem hiding this comment.
Clean, focused fix. The new InvalidExports diagnostic is symmetric with the existing MissingExports check and runs for both workspace members and links. Unit test directly verifies the diagnostic; spec test confirms user-visible behavior.
One observation (non-blocking): resolver_jsr_pkgs at libs/config/workspace/mod.rs:953 still drops the package via .ok()?, so resolution still falls back to the registry — the warning is what tells the user why. That seems like the right scope for this PR.
The flaky node_compat::internet::test-dns-any.js shard is unrelated.
…es (denoland#34473) When you use `links` (formerly `patch`) to point a JSR dependency at a local package, and that local package's `deno.json` has an **invalid `exports` map** (e.g. a key like `"types"` instead of `"./types"`), Deno would silently ignore the linked package and fall back to fetching it from the JSR registry. The user was then greeted with a confusing error: ``` error: JSR package not found: @deno/i-dont-exist-yet ``` …with no hint that the real problem was a typo in the `exports` map — not even in the internal logs. ## Cause `Workspace::resolver_jsr_pkgs()` builds the list of resolvable workspace/linked JSR packages and parses each package's `exports` map with `config_file.to_exports_config().ok()?`. The `.ok()?` silently converts a parse error into `None`, dropping the entire package from the list. With the package gone, the bare specifier no longer resolves locally and resolution falls back to the registry. Fixes denoland#25435. Co-authored-by: divybot <[email protected]> Co-authored-by: Divy Srivastava <[email protected]>
When you use
links(formerlypatch) to point a JSR dependency at a localpackage, and that local package's
deno.jsonhas an invalidexportsmap(e.g. a key like
"types"instead of"./types"), Deno would silently ignorethe linked package and fall back to fetching it from the JSR registry. The user
was then greeted with a confusing error:
…with no hint that the real problem was a typo in the
exportsmap — not evenin the internal logs.
Cause
Workspace::resolver_jsr_pkgs()builds the list of resolvable workspace/linkedJSR packages and parses each package's
exportsmap withconfig_file.to_exports_config().ok()?. The.ok()?silently converts a parseerror into
None, dropping the entire package from the list. With the packagegone, the bare specifier no longer resolves locally and resolution falls back to
the registry.
Fix
Add a new
WorkspaceDiagnosticKind::InvalidExportsdiagnostic and validate theexportsmap of every config file — both workspace members and links — inWorkspace::diagnostics(). The error message produced byto_exports_config()is already clear and actionable, so the user now sees, for example:
instead of silence. This is consistent with how Deno already surfaces other
config problems (
MissingExports,InvalidMemberName, etc.) as workspacediagnostics.
Tests
test_link_invalid_exportsindeno_configverifying thediagnostic is emitted for a linked package with an invalid
exportsmap.tests/specs/jsr/link_invalid_exportscovering both a validexportsmap (resolves locally, no warning, no registry fetch) and an invalidone (warning surfaced).
Fixes #25435.
Closes denoland/orchid#272