{"record":{"id":"982a3b34b2fc3912","repo":"astral-sh/uv","slug":"multiple-pylock-toml-files-specified-vs","errorCode":null,"errorMessage":"Multiple `pylock.toml` files specified: `{}` vs. `{}`","messagePattern":"Multiple `pylock\\.toml` files specified: `(.+?)` vs\\. `(.+?)`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/uv-requirements/src/specification.rs","lineNumber":564,"sourceCode":"        }\n\n        // Read all requirements, and keep track of all requirements _and_ constraints.\n        // A `requirements.txt` can contain a `-c constraints.txt` directive within it, so reading\n        // a requirements file can also add constraints.\n        for source in requirement_sources {\n            spec.requirements.extend(source.requirements);\n            spec.constraints.extend(source.constraints);\n            spec.overrides.extend(source.overrides);\n            spec.override_dependencies\n                .extend(source.override_dependencies);\n            spec.excludes.extend(source.excludes);\n            spec.extras.extend(source.extras);\n            spec.source_trees.extend(source.source_trees);\n\n            // Allow at most one `pylock.toml`.\n            if let Some(pylock) = source.pylock {\n                if let Some(existing) = spec.pylock {\n                    return Err(anyhow::anyhow!(\n                        \"Multiple `pylock.toml` files specified: `{}` vs. `{}`\",\n                        existing.user_display(),\n                        pylock.user_display()\n                    ));\n                }\n                spec.pylock = Some(pylock);\n            }\n\n            // Use the first project name discovered.\n            if spec.project.is_none() {\n                spec.project = source.project;\n            }\n\n            if let Some(index_url) = source.index_url {\n                if let Some(existing) = spec.index_url\n                    && CanonicalUrl::new(index_url.url().clone())\n                        != CanonicalUrl::new(existing.url().clone())\n                {","sourceCodeStart":546,"sourceCodeEnd":582,"githubUrl":"https://github.com/astral-sh/uv/blob/f1a42680ff5272232d65748acf338b19778dde24/crates/uv-requirements/src/specification.rs#L546-L582","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove one of the two pylock references named in the message so only a single pylock.toml is supplied per invocation.","If both are needed at different times, split the work into two separate uv commands instead of merging sources.","Regenerate the requirements source (without embedded pylock metadata) if it was produced by a tool that recorded the lock automatically."],"exampleFix":"# before\nuv pip compile --pylock pylock.toml -r reqs-with-pylock.txt\n# after\nuv pip compile --pylock pylock.toml -r reqs.txt   # reqs.txt no longer references a pylock","handlingStrategy":"validation","validationCode":"# Rust: before merging sources, assert at most one pylock\nlet pylocks: Vec<_> = sources\n    .iter()\n    .filter_map(|s| s.pylock.as_ref())\n    .collect();\nif pylocks.len() > 1 {\n    return Err(anyhow::anyhow!(\n        \"refusing to merge: multiple pylock.toml sources: {}\",\n        pylocks.iter().map(|p| p.user_display().to_string()).collect::<Vec<_>>().join(\", \")\n    ));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep exactly one source of lock truth per uv invocation; never pass a pylock via both a file and a flag.","When layering requirement files in scripts, grep them for pylock references before combining.","Document in CI which artifact is the lock input so future edits don't silently add a second one."],"tags":["pylock","requirements","configuration","merge"],"backgroundTag":null,"analyzedSha":"f1a42680ff5272232d65748acf338b19778dde24","analyzedAt":"2026-08-16T04:51:47.599Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}