denoland/deno · error
Could not resolve package req '{}' from graph because it was
Error message
Could not resolve package req '{}' from graph because it was missing in the provided npm snapshot. What it means
When the graph contains an npm module, eszip looks its package requirement up in the provided validated npm resolution snapshot's root_packages map. If the req from the graph is not a root package of that snapshot, creation fails: the graph and the snapshot came from different resolutions.
Source
Thrown at libs/eszip/v2.rs:1496
}
deno_graph::Module::Json(module) => {
let eszip_module = EszipV2Module::Module {
kind: ModuleKind::Json,
source: EszipV2SourceSlot::Ready(module.source.text.clone().into()),
source_map: EszipV2SourceSlot::Ready(Arc::new([])),
};
modules.insert(specifier_key.into_owned(), eszip_module);
Ok(None)
}
deno_graph::Module::Npm(module) => {
let Some(npm_packages) = npm_packages else {
return Ok(None);
};
let req_ref = &module.pkg_req_ref;
let serialize_npm_snapshot = npm_snapshot.as_serialized();
let pkg_id = serialize_npm_snapshot.root_packages.get(req_ref.req())
.ok_or_else(|| anyhow::anyhow!("Could not resolve package req '{}' from graph because it was missing in the provided npm snapshot.", req_ref.req()))?;
let pkg_nv = &pkg_id.nv;
let pkg_nv_reference =
NpmPackageNvReference::new(PackageNvReference {
nv: pkg_nv.clone(),
sub_path: req_ref.sub_path().map(|s| s.into()),
});
if visited.should_visit_package_meta() {
let meta_modules = npm_packages.take_meta_modules(pkg_nv.clone());
let package_jsons = npm_packages.take_package_jsons(pkg_nv.clone());
for meta_module in
meta_modules.into_iter().chain(package_jsons).flatten()
{
modules.insert(
meta_module.specifier,
EszipV2Module::Module {
kind: ModuleKind::OpaqueData,View on GitHub (pinned to 89f33cbef2)
Solutions
- Regenerate the lockfile/resolution so graph and snapshot come from one pass: `deno cache --lock-write` then rebuild the compile output
- Clear cached state (lockfile, node_modules, DENO_DIR npm cache) and rebuild
- If driving eszip programmatically, capture the snapshot from the same resolve pass that built the graph
Example fix
# before — graph resolved against new deps, snapshot from old lockfile deno compile entry.ts # Could not resolve package req ... missing in the provided npm snapshot # after — regenerate the lockfile so both share one resolution, then compile deno cache --lock-write entry.ts && deno compile entry.ts
Defensive patterns
Strategy: validation
Validate before calling
// every npm req in the graph must be a root package of the snapshot
for module in graph.modules() {
if let deno_graph::Module::Npm(npm) = module {
let req = npm.pkg_req_ref.req();
if !snapshot.root_packages.contains_key(req) {
anyhow::bail!("req {req} missing from npm snapshot — regenerate the lockfile");
}
}
} Prevention
- Regenerate the lockfile whenever npm dependencies change: `deno cache --lock-write`
- Capture the npm snapshot from the same resolve pass that built the graph
- Do not mix graph, snapshot and lockfile artifacts from different Deno versions in one pipeline
When it happens
Trigger: Building an eszip/compile output where the ModuleGraph was resolved against one npm state but the SerializedNpmResolutionSnapshot came from another — stale lockfile, node_modules changed between graph build and snapshot capture, mixed Deno versions in one pipeline.
Common situations: `deno compile` after editing npm dependencies without updating the lockfile; CI caching the lockfile but not node_modules (or vice versa); custom tooling assembling graph and snapshot from separate runs.
Related errors
- module not found {}
- failed to load '{}': {}
- unsupported media type {} for {}
- missing index '{}'
- Expected the second argument to assertSnapshot() to be an op
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/4459b7d713e71ffd.
Report an issue: GitHub.