[agent] Found by the scheduled Deno bug-hunt routine (ledger #308).
Summary
DenoCrawler::get_jsr_cache_paths (local mode, with no --global-prefix) returns only $DENO_DIR/npm/jsr.io. No Deno release creates that directory. Deno 1.46.3 and 2.9.6 were both checked: JSR modules are cached content-addressed under $DENO_DIR/remote/https/jsr.io/…, and $DENO_DIR/npm/jsr.io never exists.
Deno does have a stable <scope>/<name>/<version>/ layout that matches the crawler's expected shape exactly: a project with "vendor": true in deno.json (supported since Deno 1.37) gets ./vendor/jsr.io/@std/path/1.0.8/join.ts. Deno loads the code from there and allows edits to it. The crawler never looks there, though, so every pkg:jsr/... patch in a real project reports package_not_installed. Pointing --global-prefix at ./vendor/jsr.io by hand applies the same patch correctly, and Deno then runs the patched code.
The module doc (deno_crawler.rs:24-32) says the expected layout exists so that "any future Deno that adopts a stable scope/name/version layout … gets picked up automatically". Deno's vendor directory is that layout, and it isn't picked up.
Impact
For Deno, docs/ecosystems.md lists agent mode as the only supported mode ("✅ apply-only"; vendored and hosted are refused), and README says Deno patches attest via agent mode plus setup.manual. In practice, with no hand-supplied --global-prefix, a JSR patch can't be discovered or applied in any real Deno project. scan reports scannedPackages: 0 and apply reports package_not_installed. The run does fail loudly (partialFailure), so this is a missing-coverage bug, not a silent one. But the one layout that could work out of the box (vendor: true) doesn't.
Repro (Linux; Deno 2.9.6; no API needed)
set -u
SP=/path/to/socket-patch # main f6b7fb9
mkdir jsr-vendor && cd jsr-vendor; export DENO_DIR=$PWD/.dd
echo '{"vendor":true,"imports":{"@std/path":"jsr:@std/[email protected]"}}' > deno.json
echo 'import {join} from "@std/path"; join("a","b"); console.log("loaded-patched="+JSON.stringify((globalThis as any).__SP||[]));' > probe.ts
deno cache probe.ts
ls vendor/jsr.io/@std/path/1.0.8/join.ts # exists
ls "$DENO_DIR/npm/jsr.io" # No such file or directory
# local manifest + blobs: a patch for pkg:jsr/@std/[email protected] file package/join.ts that prepends
# globalThis.__SP=(globalThis.__SP||[]).concat(["path"]);
python3 mkman.py . "pkg:jsr/@std/[email protected]=vendor/jsr.io/@std/path/1.0.8:join.ts"
$SP apply --offline --json # partialFailure, package_not_installed
deno run probe.ts # loaded-patched=[]
$SP apply --offline --json --global-prefix "$PWD/vendor/jsr.io" # success, applied
deno run probe.ts # loaded-patched=["path"]
SOCKET_PROXY_URL=<mock> socket-patch scan --json in the same project reports scannedPackages: 0.
Expected vs actual
- Expected: local agent-mode discovery in a Deno project (
is_deno_project already gates on deno.json / deno.jsonc / deno.lock) also probes the project's vendor directory: ./vendor/jsr.io, or the vendor directory Deno uses for that config. That way JSR patches apply without a hand-written --global-prefix, matching the Deno row in docs/ecosystems.md and the crawler's own "picked up automatically" promise.
- Actual: only the never-created
$DENO_DIR/npm/jsr.io is probed, so JSR patches are package_not_installed.
Matrix (Linux sandbox, real Deno, runtime-checked)
| Deno |
$DENO_DIR/npm/jsr.io created? |
local apply (vendor: true) |
apply --global-prefix vendor/jsr.io |
| 1.46.3 |
no |
fail (package_not_installed) |
pass, patched code runs |
| 2.0.6 |
– |
fail |
pass |
| 2.2.15 |
– |
fail |
pass |
| 2.9.6 |
no |
fail (reproduced twice) |
pass |
macOS and Windows weren't probed for this one; the path logic isn't OS-specific. Releases 3.3.0 and 4.0.0 weren't bisected, since the crawler hasn't changed this path.
Suspect code
crates/socket-patch-core/src/crawlers/deno_crawler.rs:65-81: get_jsr_cache_paths returns only deno_dir().join("npm").join("jsr.io").
- The same function feeds both
find_by_purls (apply / rollback) and crawl_all (scan).
Related: #26 (added --global-prefix support for Deno).
[agent] Found by the scheduled Deno bug-hunt routine (ledger #308).
Summary
DenoCrawler::get_jsr_cache_paths(local mode, with no--global-prefix) returns only$DENO_DIR/npm/jsr.io. No Deno release creates that directory. Deno 1.46.3 and 2.9.6 were both checked: JSR modules are cached content-addressed under$DENO_DIR/remote/https/jsr.io/…, and$DENO_DIR/npm/jsr.ionever exists.Deno does have a stable
<scope>/<name>/<version>/layout that matches the crawler's expected shape exactly: a project with"vendor": trueindeno.json(supported since Deno 1.37) gets./vendor/jsr.io/@std/path/1.0.8/join.ts. Deno loads the code from there and allows edits to it. The crawler never looks there, though, so everypkg:jsr/...patch in a real project reportspackage_not_installed. Pointing--global-prefixat./vendor/jsr.ioby hand applies the same patch correctly, and Deno then runs the patched code.The module doc (
deno_crawler.rs:24-32) says the expected layout exists so that "any future Deno that adopts a stable scope/name/version layout … gets picked up automatically". Deno's vendor directory is that layout, and it isn't picked up.Impact
For Deno, docs/ecosystems.md lists agent mode as the only supported mode ("✅ apply-only"; vendored and hosted are refused), and README says Deno patches attest via agent mode plus
setup.manual. In practice, with no hand-supplied--global-prefix, a JSR patch can't be discovered or applied in any real Deno project.scanreportsscannedPackages: 0andapplyreportspackage_not_installed. The run does fail loudly (partialFailure), so this is a missing-coverage bug, not a silent one. But the one layout that could work out of the box (vendor: true) doesn't.Repro (Linux; Deno 2.9.6; no API needed)
SOCKET_PROXY_URL=<mock> socket-patch scan --jsonin the same project reportsscannedPackages: 0.Expected vs actual
is_deno_projectalready gates ondeno.json/deno.jsonc/deno.lock) also probes the project's vendor directory:./vendor/jsr.io, or thevendordirectory Deno uses for that config. That way JSR patches apply without a hand-written--global-prefix, matching the Deno row in docs/ecosystems.md and the crawler's own "picked up automatically" promise.$DENO_DIR/npm/jsr.iois probed, so JSR patches arepackage_not_installed.Matrix (Linux sandbox, real Deno, runtime-checked)
$DENO_DIR/npm/jsr.iocreated?apply(vendor: true)apply --global-prefix vendor/jsr.iomacOS and Windows weren't probed for this one; the path logic isn't OS-specific. Releases 3.3.0 and 4.0.0 weren't bisected, since the crawler hasn't changed this path.
Suspect code
crates/socket-patch-core/src/crawlers/deno_crawler.rs:65-81:get_jsr_cache_pathsreturns onlydeno_dir().join("npm").join("jsr.io").find_by_purls(apply / rollback) andcrawl_all(scan).Related: #26 (added
--global-prefixsupport for Deno).