denoland/deno · error
package name must use the '@<scope>/<package>' format
Error message
package name must use the '@<scope>/<package>' format
What it means
`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.
Source
Thrown at cli/registry.rs:242
/// Splits a fully qualified JSR package name (e.g. `@scope/package`) into its
/// `(scope, package)` parts.
pub fn parse_package_name(name: &str) -> Result<(&str, &str), AnyError> {
// Keep the explicit path-safety checks below even if the JSR grammar changes.
let reference = JsrPackageReqReference::from_str(&format!("jsr:{name}@*"))
.map_err(|_| {
deno_core::anyhow::anyhow!(
"package name must use the '@<scope>/<package>' format"
)
})?;
if reference.sub_path().is_some() {
bail!("package name must not contain additional path segments");
}
let Some((scope, package)) =
name.strip_prefix('@').and_then(|name| name.split_once('/'))
else {
bail!("package name must use the '@<scope>/<package>' format");
};
for component in [scope, package] {
if component == "." || component == ".." {
bail!("package name must not contain dot path segments");
}
if component
.chars()
.any(|c| matches!(c, '/' | '\\' | '?' | '#' | '%'))
{
bail!("package name contains a URL path or delimiter character");
}
}
Ok((scope, package))
}
/// Returns `true` if the given package version is already published to the
/// registry.
///View on GitHub (pinned to f7822238ca)
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)
Example fix
// before
parse_package_name("my-package")?;
// after
parse_package_name("@my-scope/my-package")?; Defensive patterns
Strategy: validation
Validate before calling
fn is_qualified_jsr_name(name: &str) -> bool {
let Some(rest) = name.strip_prefix('@') else { return false };
match rest.split_once('/') {
Some((scope, pkg)) => !scope.is_empty() && !pkg.is_empty(),
None => false,
}
}
assert!(is_qualified_jsr_name("@my-scope/my-package"));
let (scope, package) = parse_package_name(name)?; Type guard
fn is_qualified_jsr_name(name: &str) -> bool {
name.starts_with('@')
&& name.strip_prefix('@').and_then(|r| r.split_once('/'))
.map(|(s, p)| !s.is_empty() && !p.is_empty())
.unwrap_or(false)
} Try / catch
match parse_package_name(name) {
Ok((scope, package)) => /* use scope/package */,
Err(e) if e.to_string().contains("'@<scope>/<package>' format") => {
eprintln!("name must look like @scope/package; got {name:?}");
std::process::exit(2);
}
Err(e) => return Err(e),
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid package name '{}'. Package name must be in the forma
- package name must not contain additional path segments
- package name must not contain dot path segments
- package name contains a URL path or delimiter character
- refusing to write tarball with unsafe name derived from pack
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-29).
Data as JSON: /api/errors/371d9ef47190d980.
Report an issue: GitHub.