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

The file `{}` appears to be a `pylock.toml` file, but constr

Error message

The file `{}` appears to be a `pylock.toml` file, but constraints must be specified in `requirements.txt` format

What it means

Thrown by RequirementsSource::from_constraints_txt (crates/uv-requirements/src/sources.rs:135) when the file passed via --constraints/-c has a file name recognized as a pylock.toml lock file (is_pylock_toml matches pylock.toml and its versioned variants). Constraint files must use the requirements.txt format (bare `name==version` pins), and a PEP 751 lock file cannot fulfill that role. uv aborts up front instead of mis-parsing the TOML as requirements syntax.

Source

Thrown at crates/uv-requirements/src/sources.rs:135

        if path == Path::new("-") {
            return Ok(Self::Extensionless(path));
        }

        for file_name in ["pyproject.toml", "setup.py", "setup.cfg"] {
            if path.ends_with(file_name) {
                return Err(anyhow::anyhow!(
                    "The file `{}` appears to be a `{}` file, but constraints must be specified in `requirements.txt` format",
                    path.user_display(),
                    file_name
                ));
            }
        }
        if path
            .file_name()
            .and_then(OsStr::to_str)
            .is_some_and(is_pylock_toml)
        {
            return Err(anyhow::anyhow!(
                "The file `{}` appears to be a `pylock.toml` file, but constraints must be specified in `requirements.txt` format",
                path.user_display(),
            ));
        } else if path
            .extension()
            .is_some_and(|ext| ext.eq_ignore_ascii_case("toml"))
        {
            return Err(anyhow::anyhow!(
                "The file `{}` appears to be a TOML file, but constraints must be specified in `requirements.txt` format",
                path.user_display(),
            ));
        }
        Ok(Self::RequirementsTxt(path))
    }

    /// Parse a [`RequirementsSource`] from an `overrides.txt` file.
    pub fn from_overrides_txt(path: PathBuf) -> Result<Self> {
        if path == Path::new("-") {

View on GitHub (pinned to f1a42680ff)

Solutions

  1. Pass a requirements.txt-format constraints file instead: `uv pip install -c constraints.txt ...` where each line is `package==version`
  2. Generate constraints from your lock with `uv export --format requirements-txt -o constraints.txt` and use that file
  3. If your goal is to reproduce the locked environment, use `uv sync` or `uv pip install -r pylock.toml` rather than --constraints

Example fix

# before
uv pip install -c pylock.toml flask
# after
uv export --format requirements-txt -o constraints.txt
uv pip install -c constraints.txt flask
Defensive patterns

Strategy: validation

Validate before calling

fn is_pylock_toml_name(path: &Path) -> bool {
    path.file_name()
        .and_then(std::ffi::OsStr::to_str)
        .is_some_and(|name| {
            name == "pylock.toml" || (name.starts_with("pylock.") && name.ends_with(".toml"))
        })
}

// before calling from_constraints_txt:
if is_pylock_toml_name(&path) {
    return Err(anyhow::anyhow!("{path:?} is a lock file; use a requirements.txt-format constraints file"));
}

Try / catch

match RequirementsSource::from_constraints_txt(path) {
    Err(err) if err.to_string().contains("pylock.toml") => {
        // fall back to exporting constraints from the lock
    }
    source => source?,
}

Prevention

When it happens

Trigger: Running `uv pip install -c pylock.toml flask` or `uv pip compile --constraints pylock.toml`, or calling RequirementsSource::from_constraints_txt(PathBuf::from("pylock.toml")) programmatically; `is_pylock_toml` matches the file-name component (e.g. pylock.2020.dev.toml variants also match).

Common situations: Teams migrating from pip-tools try to reuse an exported lock file as constraints; CI scripts point --constraints at a generated pylock.toml; users assume a lock file and a constraints file are interchangeable.

Related errors


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