astral-sh/uv · error · anyhow::Error

Cannot use `{}` as a constraint file

Error message

Cannot use `{}` as a constraint file

What it means

Thrown in RequirementsSpecification::from_sources (crates/uv-requirements/src/specification.rs:426) when any source in the constraints list is already a RequirementsSource::PylockToml variant. This is the aggregation-level guard that complements error 40: even when sources were constructed through a path that bypassed from_constraints_txt's file-name sniffing, a pylock.toml can never act as a constraint file.

Source

Thrown at crates/uv-requirements/src/specification.rs:426

        requirements: &[RequirementsSource],
        constraints: &[RequirementsSource],
        overrides: &[RequirementsSource],
        excludes: &[RequirementsSource],
        groups: Option<&GroupsSpecification>,
        client_builder: &BaseClientBuilder<'_>,
    ) -> Result<Self> {
        let mut spec = Self::default();
        let mut cache = SourceCache::default();

        // Disallow `pylock.toml` files as constraints.
        if let Some(pylock_toml) = constraints.iter().find_map(|source| {
            if let RequirementsSource::PylockToml(path) = source {
                Some(path)
            } else {
                None
            }
        }) {
            return Err(anyhow::anyhow!(
                "Cannot use `{}` as a constraint file",
                pylock_toml.user_display()
            ));
        }

        // Disallow `pylock.toml` files as overrides.
        if let Some(pylock_toml) = overrides.iter().find_map(|source| {
            if let RequirementsSource::PylockToml(path) = source {
                Some(path)
            } else {
                None
            }
        }) {
            return Err(anyhow::anyhow!(
                "Cannot use `{}` as an override file",
                pylock_toml.user_display()
            ));
        }

View on GitHub (pinned to f1a42680ff)

Solutions

  1. Remove the pylock.toml entry from the constraints list — constraints must be requirements.txt-format sources
  2. Export the lock to requirements format and use that as the constraint source
  3. If the intent was exact-lock installation, move pylock.toml into requirements (`-r pylock.toml`) and drop --constraints entirely (see error 57)

Example fix

# before (programmatic)
let spec = RequirementsSpecification::from_sources(
    vec![RequirementsSource::PylockToml(lock.into())], /* ... */
// after
let spec = RequirementsSpecification::from_sources(
    vec![RequirementsSource::RequirementsTxt(constraints.into())], /* ... */
Defensive patterns

Strategy: validation

Validate before calling

let bad = constraints.iter().any(|s| matches!(s, RequirementsSource::PylockToml(_)));
if bad {
    return Err(anyhow::anyhow!("refusing to assemble spec: pylock.toml is not a constraint source"));
}

Type guard

fn is_pylock_source(s: &RequirementsSource) -> bool {
    matches!(s, RequirementsSource::PylockToml(_))
}

Try / catch

match RequirementsSpecification::from_sources(requirements, constraints, overrides, /* .. */).await {
    Err(err) if err.to_string().contains("as a constraint file") => {
        // strip pylock sources from constraints and reassemble
    }
    spec => spec?,
}

Prevention

When it happens

Trigger: Programmatically calling from_sources with a PylockToml source in the constraints Vec; CLI flows where a constraint path was resolved to a pylock source upstream (e.g. `--constraints pylock.toml` reaching this constructor); only the first offending path is reported.

Common situations: Wrapper tools building RequirementsSpecification directly from mixed source lists; scripts that glob *.toml into constraint paths; lock-and-constrain hybrid CI setups.

Related errors


AI-assisted analysis of astral-sh/uv@f1a42680ff (2026-08-16). Data as JSON: /api/errors/75decd4be17b79a0. Report an issue: GitHub.