denoland/deno · error
package name contains a URL path or delimiter character
Error message
package name contains a URL path or delimiter character
What it means
`parse_package_name` rejects scope or package components containing URL path or delimiter characters — `/`, `\`, `?`, `#`, `%` — because these characters would change how the name is embedded into registry URLs (path separators, query, fragment, percent-encoding) and enable name smuggling. If either component contains any of them, this error is raised.
Source
Thrown at cli/registry.rs:252
})?;
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.
///
/// Only a `200 OK` response is treated as "already published". A `404` (and any
/// other non-success status) is treated as "not published" so that this
/// up-front optimization never blocks a legitimate publish because of a
/// transient registry error.
pub async fn check_version_exists(
client: &HttpClient,
registry_api_url: &Url,
scope: &str,
package: &str,
version: &str,View on GitHub (pinned to f7822238ca)
Solutions
- Strip the URL/query/fragment portion and pass only the bare `@<scope>/<package>` identifier
- Percent-decode the string first if it may be URL-encoded, then re-validate
- Sanitize the name to remove `/`, `\`, `?`, `#`, `%` or reject it before calling
Example fix
// before
parse_package_name("@my-scope/my-pkg?version=1")?;
// after
parse_package_name("@my-scope/my-pkg")?; Defensive patterns
Strategy: validation
Validate before calling
const RESERVED = /[\/\\?#%]/;
function is_clean_jsr_name(name) {
if (!name.startsWith("@")) return false;
const [, rest] = [name.slice(1), name.slice(1)];
const [scope, pkg] = rest.split("/");
if (!scope || !pkg || pkg.includes("/")) return false;
return !RESERVED.test(scope) && !RESERVED.test(pkg);
}
if (!is_clean_jsr_name(name)) throw new Error("strip URL delimiters from the package name"); Type guard
fn has_no_url_delimiters(name: &str) -> bool {
!name.chars().any(|c| matches!(c, '/' | '\\' | '?' | '#' | '%'))
} Try / catch
match parse_package_name(name) {
Ok((scope, package)) => /* use scope/package */,
Err(e) if e.to_string().contains("URL path or delimiter") => {
eprintln!("pass the bare name, not a URL: got {name:?}");
}
Err(e) => return Err(e),
} Prevention
- Pass identifiers, never URLs or query strings, into package-name parameters
- Percent-decode user input before validating, then re-validate for reserved characters
- On Windows, normalize backslashes to forward slashes and re-split rather than letting `\` leak into components
- Add a regex validator (reject `[\/\\?#%]`) at every boundary where a package name enters your tooling
When it happens
Trigger: Passing a name such as `@scope/pkg?x=1`, `@scope/sub/pkg`, `@scope/pkg%20x`, or `@scope/pkg#frag` into `parse_package_name`; also names that survived URL decoding/encoding rounds and still carry reserved characters.
Common situations: Passing a full URL or URL fragment instead of a bare package name; double-splitting a name so a second `/` lands inside the package component; names read from query strings or configs without URL-decoding; Windows paths leaking backslashes.
Related errors
- Invalid package name '{}'. Package name must be in the forma
- package name must not contain additional path segments
- package name must use the '@<scope>/<package>' format
- package name must not contain dot path segments
- Request url protocol must be 'http:' or 'https:': received '
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-29).
Data as JSON: /api/errors/cf54a4fb38bb5fef.
Report an issue: GitHub.