{"record":{"id":"2abb73c81cbf65ae","repo":"denoland/deno","slug":"missing-version-in-package-json-of-npm-package","errorCode":null,"errorMessage":"missing version in package.json of npm package","messagePattern":"missing version in package\\.json of npm package","errorType":"exception","errorClass":"AnyError","httpStatus":null,"severity":"error","filePath":"cli/tools/publish/unfurl.rs","lineNumber":680,"sourceCode":"  }\n\n  fn find_workspace_npm_dep_version(\n    &self,\n    pkg_name: &str,\n  ) -> Result<Version, anyhow::Error> {\n    // todo(#24612): warn when this is also a jsr package telling\n    // people to map the specifiers in the import map\n    let pkg_json = self\n      .workspace_resolver\n      .package_jsons()\n      .find(|pkg| pkg.name.as_deref() == Some(pkg_name))\n      .ok_or_else(|| {\n        anyhow::anyhow!(\"unable to find npm package in workspace\")\n      })?;\n    if let Some(version) = &pkg_json.version {\n      Ok(Version::parse_from_npm(version)?)\n    } else {\n      Err(anyhow::anyhow!(\n        \"missing version in package.json of npm package\",\n      ))\n    }\n  }\n\n  /// Look up the version constraint for a @types/* package from package.json\n  /// dependencies (including devDependencies) or from the import map.\n  fn find_types_package_version_req(\n    &self,\n    types_package_name: &str,\n    referrer: &ModuleSpecifier,\n  ) -> Option<VersionReq> {\n    // check package.json dependencies\n    let referrer_path = deno_path_util::url_to_file_path(referrer).ok();\n    let referrer_pkg_jsons = referrer_path\n      .as_ref()\n      .map(|path| self.pkg_json_resolver.get_closest_package_jsons(path))\n      .into_iter()","sourceCodeStart":662,"sourceCodeEnd":698,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/tools/publish/unfurl.rs#L662-L698","documentation":"Companion to 'unable to find npm package in workspace': the specifier DID match a workspace package.json by name, but that package.json has no top-level `version` field, so Deno cannot determine which version to unfurl the specifier to. Deno reads `pkg_json.version` and parses it with `Version::parse_from_npm`, requiring a plain semver string.","triggerScenarios":"A local workspace npm package whose package.json omits `version` (common for private app crates where version is irrelevant); a version field set to a non-semver value would instead fail parsing; the package is imported by a JSR package being published, triggering the lookup.","commonSituations":"Monorepos mixing an npm package (never published, no version) with a JSR package that imports it; templates generated without version; users surprised that internal-use packages still need version when referenced from publishable code.","solutions":["Add a plain semver `\"version\": \"1.0.0\"` (or the real version) to the matched package's package.json.","Ensure the value is a bare semver version — no 'v' prefix, no range operators like '^'/'~' (Version::parse_from_npm rejects those).","If the import was accidental (leftover from prototyping), remove the import or redirect it to the correct dependency instead of versioning a dummy package."],"exampleFix":"// before (package.json)\n{\n  \"name\": \"my-pkg\",\n  \"exports\": \"./mod.ts\"\n}\n\n// after\n{\n  \"name\": \"my-pkg\",\n  \"version\": \"1.0.0\",\n  \"exports\": \"./mod.ts\"\n}","handlingStrategy":"validation","validationCode":"const pkgJson = JSON.parse(await Deno.readText('package.json'));\nif (typeof pkgJson.version !== 'string' || !/^\\d+\\.\\d+\\.\\d+/.test(pkgJson.version)) {\n  throw new Error('workspace npm package needs a plain semver \"version\" field');\n}","typeGuard":"function hasSemverVersion(m: { version?: unknown }): boolean {\n  return typeof m.version === 'string' && /^\\d+\\.\\d+\\.\\d+(-[\\w.-]+)?$/.test(m.version);\n}","tryCatchPattern":"try {\n  await runDeno(['publish']);\n} catch (e) {\n  if (String(e.message).includes('missing version in package.json')) {\n    // add \"version\": \"1.0.0\" to the matching package.json, then retry\n  }\n}","preventionTips":["Give every workspace package.json a version, even internal-only packages.","Use a bare semver string (no 'v' prefix, no ^/~) since the value is parsed with parse_from_npm.","Include a version check in pre-publish CI validation of workspace manifests."],"tags":["publish","jsr","npm","package-json","unfurl","version"],"backgroundTag":"missing-manifest-field","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}