astral-sh/uv · error

Multiple `pylock.toml` files specified: `{}` vs. `{}`

Error message

Multiple `pylock.toml` files specified: `{}` vs. `{}`

What it means

Thrown while merging multiple requirement sources (CLI requirements, requirements.txt, constraints, overrides) into a single RequirementsSpecification. uv allows at most one pylock.toml across all merged sources; when a second source also carries a pylock (e.g., a second `--pylock` reference or a requirements file that itself pins a pylock.toml), the merge aborts. The first (existing) and conflicting paths are both printed.

Source

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

        }

        // Read all requirements, and keep track of all requirements _and_ constraints.
        // A `requirements.txt` can contain a `-c constraints.txt` directive within it, so reading
        // a requirements file can also add constraints.
        for source in requirement_sources {
            spec.requirements.extend(source.requirements);
            spec.constraints.extend(source.constraints);
            spec.overrides.extend(source.overrides);
            spec.override_dependencies
                .extend(source.override_dependencies);
            spec.excludes.extend(source.excludes);
            spec.extras.extend(source.extras);
            spec.source_trees.extend(source.source_trees);

            // Allow at most one `pylock.toml`.
            if let Some(pylock) = source.pylock {
                if let Some(existing) = spec.pylock {
                    return Err(anyhow::anyhow!(
                        "Multiple `pylock.toml` files specified: `{}` vs. `{}`",
                        existing.user_display(),
                        pylock.user_display()
                    ));
                }
                spec.pylock = Some(pylock);
            }

            // Use the first project name discovered.
            if spec.project.is_none() {
                spec.project = source.project;
            }

            if let Some(index_url) = source.index_url {
                if let Some(existing) = spec.index_url
                    && CanonicalUrl::new(index_url.url().clone())
                        != CanonicalUrl::new(existing.url().clone())
                {

View on GitHub (pinned to f1a42680ff)

Solutions

  1. Remove one of the two pylock references named in the message so only a single pylock.toml is supplied per invocation.
  2. If both are needed at different times, split the work into two separate uv commands instead of merging sources.
  3. Regenerate the requirements source (without embedded pylock metadata) if it was produced by a tool that recorded the lock automatically.

Example fix

# before
uv pip compile --pylock pylock.toml -r reqs-with-pylock.txt
# after
uv pip compile --pylock pylock.toml -r reqs.txt   # reqs.txt no longer references a pylock
Defensive patterns

Strategy: validation

Validate before calling

# Rust: before merging sources, assert at most one pylock
let pylocks: Vec<_> = sources
    .iter()
    .filter_map(|s| s.pylock.as_ref())
    .collect();
if pylocks.len() > 1 {
    return Err(anyhow::anyhow!(
        "refusing to merge: multiple pylock.toml sources: {}",
        pylocks.iter().map(|p| p.user_display().to_string()).collect::<Vec<_>>().join(", ")
    ));
}

Prevention

When it happens

Trigger: Passing two files that each reference a pylock.toml to `uv pip compile`/`uv sync`/`uv lock` (e.g., `--requirements a/pylock.toml --requirements b/pylock.toml`), or combining `-r requirements.txt` (which records a pylock) with an explicit `--pylock pylock.toml` on the same invocation.

Common situations: Scripts that layer a lockfile on top of a requirements file that already embeds lock metadata; CI pipelines upgrading to a setup where pylock.toml is auto-discovered plus an explicit flag; migrating from one pylock location to another while the old one is still listed in config.

Related errors


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