denoland/deno · error · anyhow::Error

missing version in package.json of npm package

Error message

missing version in package.json of npm package

What it means

Companion to the workspace npm lookup: a package.json with the matching `name` was found, but it has no `version` field, so there is no version to pin into the unfurled specifier and publish fails. npm packages used as workspace dependencies must declare a semver version.

Source

Thrown at cli/tools/publish/unfurl.rs:680

  }

  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 dependencies
    let referrer_path = deno_path_util::url_to_file_path(referrer).ok();
    let referrer_pkg_jsons = referrer_path
      .as_ref()
      .map(|path| self.pkg_json_resolver.get_closest_package_jsons(path))
      .into_iter()

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Add a valid semver `"version"` (e.g. "1.0.0") to that member's package.json
  2. Make sure the version parses per npm rules: no 'v' prefix, no ranges like ^1.0
  3. Re-run `deno publish --dry-run` to confirm the specifier pins correctly

Example fix

// before — packages/shared/package.json
{ "name": "shared-lib" }
// after
{ "name": "shared-lib", "version": "1.0.0" }
Defensive patterns

Strategy: validation

Validate before calling

# every workspace package.json must carry a version
for f in $(find . -name package.json -not -path '*/node_modules/*'); do
  jq -e 'has("version") and (.version | test("^\\d+\\.\\d+\\.\\d+"))' "$f" >/dev/null \
    || echo "missing/invalid version in $f" >&2
done

Prevention

When it happens

Trigger: A workspace member package.json declares `"name": "pkg"` but omits `"version"`, and published source imports that package, so the unfurler cannot pin a version.

Common situations: Hand-written package.json for a private workspace library that forgot `version`; scaffolding templates that omit it; malformed versions are a separate failure (Version::parse_from_npm).

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/2abb73c81cbf65ae. Report an issue: GitHub.