denoland/deno · error · AnyError
unable to find npm package in workspace
Error message
unable to find npm package in workspace
What it means
While 'unfurling' relative npm imports for publish, Deno resolves a bare npm specifier found in a source file by looking for a workspace package.json whose `name` matches (`find_workspace_npm_dep_version`). If no workspace package.json declares that exact name, resolution fails with this error — effectively the package is imported in code but not part of the workspace under that name.
Solutions
- Add the npm dependency properly so it lands in package.json: `deno add npm:my-pkg` (or manually add `"dependencies": {"my-pkg": "^1.0.0" }` to the relevant package.json).
- Fix the specifier spelling in the importing source file to exactly match the package.json `name`.
- See the adjacent todo (#24612): if the same package also exists on JSR, map it through the deno.json import map instead of relying on the npm workspace entry.
- Re-run `deno publish --dry-run` — unfurling errors surface there before upload.
Example fix
// before: src/mod.ts
import { helper } from "my-pkg"; // not declared anywhere
# after: add the dependency
# deno add npm:my-pkg
# (creates/updates package.json: { "dependencies": { "my-pkg": "^1.0.0" } }) Defensive patterns
Strategy: validation
Validate before calling
import * as path from 'node:path';
function declaredNpmNames(pkgJsons: { name?: string }[]): Set<string> {
return new Set(pkgJsons.flatMap((p) => (p.name ? [p.name] : [])));
}
// scan sources for bare specifiers and compare against package.json names
// before invoking publish
const declared = declaredNpmNames(await readWorkspacePackageJsons());
for (const spec of collectBareSpecifiers(await expand('src/**/*.ts'))) {
if (!declared.has(spec)) {
throw new Error(`npm package "${spec}" is imported but not declared in any package.json`);
}
} Type guard
const isDeclaredNpmPackage = (name: string, declared: Set<string>): boolean => declared.has(name);
Try / catch
try {
await runDeno(['publish']);
} catch (e) {
if (String(e.message).includes('unable to find npm package in workspace')) {
// the source file named in the error imports an undeclared npm package:
// run `deno add npm:<pkg>` or fix the specifier, then retry
}
} Prevention
- Add npm dependencies with `deno add npm:<pkg>` so they are recorded in package.json.
- Audit bare imports before publishing (`deno publish --dry-run` surfaces unfurling errors).
- Keep package names and their import sites spelled identically; rename both together.
When it happens
Trigger: Source contains `import ... from "my-pkg"` but no package.json in the workspace has `"name": "my-pkg"` (missing dependency, typo'd name, or a dependency that exists only in deno.json imports); importing a npm package that was never added via `deno add npm:my-pkg` in an npm-managed publish setup.
Common situations: JSR packages that also use npm deps and rely on the import map instead of package.json; renaming a local package but not its importers; scaffolding a publish from a repo where the npm dep was resolved through node_modules ad hoc.
Related errors
- missing version in package.json of npm package
- Cannot represent compiler option
- Cannot use --set-version when publishing a workspace…
- Failed to publish packages
- No packages to publish
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/e10b5419a7547a66.
Report an issue: GitHub.
Appendix: source
Thrown at cli/tools/publish/unfurl.rs:675
referrer,
relative_resolved
);
Ok(Some(relative_resolved))
}
}
fn find_workspace_npm_dep_version(
&self,
pkg_name: &str,
) -> Result<Version, anyhow::Error> {
// todo(#24612): warn when this is also a jsr package telling
// people to map the specifiers in the import map
let pkg_json = self
.workspace_resolver
.package_jsons()
.find(|pkg| pkg.name.as_deref() == Some(pkg_name))
.ok_or_else(|| {
anyhow::anyhow!("unable to find npm package in workspace")
})?;
if let Some(version) = &pkg_json.version {
Ok(Version::parse_from_npm(version)?)
} else {
Err(anyhow::anyhow!(
"missing version in package.json of npm package",
))
}
}
/// Look up the version constraint for a @types/* package from package.json
/// dependencies (including devDependencies) or from the import map.
fn find_types_package_version_req(
&self,
types_package_name: &str,
referrer: &ModuleSpecifier,
) -> Option<VersionReq> {
// check package.json dependenciesView on GitHub (pinned to 9ad36f7a2c)