{"record":{"id":"371d9ef47190d980","repo":"denoland/deno","slug":"package-name-must-use-the-scope-package-for","errorCode":null,"errorMessage":"package name must use the '@<scope>/<package>' format","messagePattern":"package name must use the '@<scope>/<package>' format","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/registry.rs","lineNumber":242,"sourceCode":"\n/// Splits a fully qualified JSR package name (e.g. `@scope/package`) into its\n/// `(scope, package)` parts.\npub fn parse_package_name(name: &str) -> Result<(&str, &str), AnyError> {\n  // Keep the explicit path-safety checks below even if the JSR grammar changes.\n  let reference = JsrPackageReqReference::from_str(&format!(\"jsr:{name}@*\"))\n    .map_err(|_| {\n      deno_core::anyhow::anyhow!(\n        \"package name must use the '@<scope>/<package>' format\"\n      )\n    })?;\n  if reference.sub_path().is_some() {\n    bail!(\"package name must not contain additional path segments\");\n  }\n\n  let Some((scope, package)) =\n    name.strip_prefix('@').and_then(|name| name.split_once('/'))\n  else {\n    bail!(\"package name must use the '@<scope>/<package>' format\");\n  };\n  for component in [scope, package] {\n    if component == \".\" || component == \"..\" {\n      bail!(\"package name must not contain dot path segments\");\n    }\n    if component\n      .chars()\n      .any(|c| matches!(c, '/' | '\\\\' | '?' | '#' | '%'))\n    {\n      bail!(\"package name contains a URL path or delimiter character\");\n    }\n  }\n  Ok((scope, package))\n}\n\n/// Returns `true` if the given package version is already published to the\n/// registry.\n///","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/registry.rs#L224-L260","documentation":"`parse_package_name` requires JSR package names to be fully qualified in the `@<scope>/<package>` form. After stripping the leading `@` it must find a `/` separating scope and package; if the name has no leading `@` or no `/` (or the stricter JsrPackageReqReference parse also fails), the name is not a valid JSR package name and this error is raised.","triggerScenarios":"Passing a bare package name (`mypackage`), a scope only (`@my-scope`), an empty string, or a name with a malformed prefix such as `@@scope/pkg` to `parse_package_name` — the `strip_prefix('@').and_then(split_once('/'))` step returns None.","commonSituations":"Using npm-style unscoped names in a JSR context; forgetting the `@` when typing a scope; shell/CI variables expanding to empty strings; splitting a full name on the wrong delimiter so only the package part survives.","solutions":["Format the name as `@<scope>/<package>`, e.g. `@my-scope/my-package` instead of `my-package`","Add the missing `@` scope prefix if the scope exists but was dropped","Check the shell/CI variable actually contains the full qualified name (echo it before calling)"],"exampleFix":"// before\nparse_package_name(\"my-package\")?;\n// after\nparse_package_name(\"@my-scope/my-package\")?;","handlingStrategy":"validation","validationCode":"fn is_qualified_jsr_name(name: &str) -> bool {\n  let Some(rest) = name.strip_prefix('@') else { return false };\n  match rest.split_once('/') {\n    Some((scope, pkg)) => !scope.is_empty() && !pkg.is_empty(),\n    None => false,\n  }\n}\nassert!(is_qualified_jsr_name(\"@my-scope/my-package\"));\nlet (scope, package) = parse_package_name(name)?;","typeGuard":"fn is_qualified_jsr_name(name: &str) -> bool {\n  name.starts_with('@')\n    && name.strip_prefix('@').and_then(|r| r.split_once('/'))\n      .map(|(s, p)| !s.is_empty() && !p.is_empty())\n      .unwrap_or(false)\n}","tryCatchPattern":"match parse_package_name(name) {\n  Ok((scope, package)) => /* use scope/package */,\n  Err(e) if e.to_string().contains(\"'@<scope>/<package>' format\") => {\n    eprintln!(\"name must look like @scope/package; got {name:?}\");\n    std::process::exit(2);\n  }\n  Err(e) => return Err(e),\n}","preventionTips":["Always write JSR names with the scope: `@scope/package`, never bare names","Guard CI/shell variables: fail fast if the name variable is empty or missing the '@'","When migrating from npm, remember JSR requires scoped names for publishing","Unit-test your name-building code with a bare-name case to catch regressions"],"tags":["jsr","package-name","validation","format"],"backgroundTag":"invalid-package-name","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-29T08:55:39.519Z","contentChangedAt":"2026-08-29T08:55:39.519Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}