astral-sh/uv · error
Unnamed requirements are not allowed as exclusions (found: `
Error message
Unnamed requirements are not allowed as exclusions (found: `{requirement}`) What it means
Exclusions (e.g., `--exclude` inputs merged in RequirementsSpecification) work by package name, so each parsed requirement must be named. When an exclusion source yields an UnresolvedRequirement::Unnamed (URL/path requirement), uv errors out during the excludes-merge loop, printing the offending requirement.
Source
Thrown at crates/uv-requirements/src/specification.rs:675
spec.no_index |= source.no_index;
spec.extra_index_urls.extend(source.extra_index_urls);
spec.find_links.extend(source.find_links);
spec.no_binary.extend(source.no_binary);
spec.no_build.extend(source.no_build);
spec.require_hashes |= source.require_hashes;
}
// Collect excludes.
for source in excludes {
let source = Self::from_source_with_cache(source, client_builder, &mut cache).await?;
for req_spec in source.requirements {
match req_spec.requirement {
UnresolvedRequirement::Named(requirement) => {
spec.excludes
.push(ExcludeDependency::Dependency(requirement.name));
}
UnresolvedRequirement::Unnamed(requirement) => {
return Err(anyhow::anyhow!(
"Unnamed requirements are not allowed as exclusions (found: `{requirement}`)"
));
}
}
}
spec.excludes.extend(source.excludes);
}
Ok(spec)
}
/// Parse an individual package requirement.
pub fn parse_package(name: &str) -> Result<UnresolvedRequirementSpecification> {
let requirement = RequirementsTxtRequirement::parse(name, &*CWD, false)
.with_context(|| format!("Failed to parse: `{name}`"))?;
Ok(UnresolvedRequirementSpecification::from(requirement))
}
View on GitHub (pinned to f1a42680ff)
Solutions
- Replace the unnamed entry with the package's name only, e.g., `--exclude my-pkg`.
- If you meant to remove a URL requirement from the resolve, delete or edit that line in the requirements source instead of using --exclude.
- For VCS/URL deps, find their distribution name (from the wheel/sdist metadata) and exclude that name.
Example fix
# before uv pip compile requirements.txt --exclude ./wheels/team-util-1.0-py3-none-any.whl # after uv pip compile requirements.txt --exclude team-util
Defensive patterns
Strategy: validation
Validate before calling
# Rust: only pass named requirements into the excludes pipeline
fn exclusion_names(reqs: &[RequirementEntry]) -> anyhow::Result<Vec<PackageName>> {
reqs.iter()
.map(|entry| match &entry.requirement {
UnresolvedRequirement::Named(r) => Ok(r.name.clone()),
UnresolvedRequirement::Unnamed(r) => {
anyhow::bail!("exclusions must be named, got: {r}")
}
})
.collect()
} Type guard
fn is_excludable(entry: &RequirementEntry) -> bool {
matches!(entry.requirement, UnresolvedRequirement::Named(_))
} Prevention
- Pass package names (not URLs/paths) to --exclude.
- When scripting exclusions from an existing requirements list, map each URL entry to its distribution name first.
When it happens
Trigger: Passing `--exclude https://github.com/org/repo` or `--exclude ./local/pkg.tar.gz` to a command that supports exclusions; feeding an exclusion file that lists a direct URL dependency instead of a package name.
Common situations: Assuming `--exclude` accepts the same syntax as requirements (URLs, paths, VCS specs); scripted dependency pruning that copies requirement lines verbatim into an exclusion list.
Related errors
- Unnamed requirements are not allowed as constraints (found:
- pip-compile's `--emit-options` is unsupported (try `--emit-b
- Extra names must start and end with a letter or digit and ma
- Cannot specify additional requirements alongside a `pylock.t
- Multiple `pylock.toml` files specified: `{}` vs. `{}`
AI-assisted analysis of astral-sh/uv@f1a42680ff (2026-08-16).
Data as JSON: /api/errors/1c74f1d5b63380f5.
Report an issue: GitHub.