denoland/deno · error

Unexpected package json dependency string: "{string_value}"

Error message

Unexpected package json dependency string: "{string_value}" in {}

What it means

When the dependency manager rewrites a version in package.json, it handles `npm:`-aliased entries and plain versions. Any other value containing `:` — `jsr:@scope/pkg@^1`, `http:...`, `git+ssh:...` — hits this bail because rewriting it would corrupt an unsupported scheme.

Source

Thrown at cli/tools/pm/deps.rs:1165

                );
                continue;
              };
              let Some(string_value) = cst_string_literal(&property) else {
                continue;
              };
              let new_value = if string_value.starts_with("npm:") {
                // aliased
                let rest = string_value.trim_start_matches("npm:");
                let mut parts = rest.split('@');
                let first = parts.next().unwrap();
                if first.is_empty() {
                  let scope_and_name = parts.next().unwrap();
                  format!("npm:@{scope_and_name}@{version_req}")
                } else {
                  format!("npm:{first}@{version_req}")
                }
              } else if string_value.contains(":") {
                bail!(
                  "Unexpected package json dependency string: \"{string_value}\" in {}",
                  arc.path.display()
                );
              } else {
                version_req.to_string()
              };
              property
                .set_value(jsonc_parser::cst::CstInputValue::String(new_value));
            }
            DepLocation::Catalog {
              path, key_paths, ..
            } => {
              let updater =
                get_or_create_updater(&mut config_updaters, &dep.location)?;
              if !updater
                .update_catalog_entry(key_paths, &version_req.to_string())
              {
                log::warn!(

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Move `jsr:` dependencies into deno.json `imports` and keep plain npm versions in package.json.
  2. For npm-aliased entries keep the `npm:name` form (supported) rather than other schemes.
  3. After editing, re-run the original command to confirm the rewrite succeeds.

Example fix

// package.json (before)
{
  "dependencies": { "my-lib": "jsr:@scope/my-lib@^1.0.0" }
}
// deno.json (after)
{
  "imports": { "my-lib": "jsr:@scope/my-lib@^1.0.0" }
}
// package.json (after)
{
  "dependencies": {}
}
Defensive patterns

Strategy: validation

Validate before calling

const pkg = JSON.parse(readFileSync("package.json", "utf8"));
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
const bad = Object.entries(deps).filter(([, v]) => v.includes(":") && !String(v).startsWith("npm:"));
if (bad.length) {
  console.error(`non-npm specifiers in package.json: ${bad.map(([k, v]) => `${k}@${v}`).join(", ")}`);
  process.exit(1);
}

Type guard

const isRewritablePkgJsonDep = (v: string): boolean =>
  !v.includes(":") || v.startsWith("npm:");

Prevention

When it happens

Trigger: `deno add`/`deno remove`/`deno install` updating a package.json whose dependencies/devDependencies contain a non-npm scheme string, e.g. `"my-lib": "jsr:@scope/my-lib@^1.0.0"`. A hand-edited package.json using jsr: or a git URL where a plain version is expected.

Common situations: Mixed Deno/npm projects that stored JSR deps in package.json; copying an import-map entry into package.json dependencies; converting npm deps to jsr without moving them to deno.json imports.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/b76ecd6c4fc126d8. Report an issue: GitHub.