astral-sh/uv · error · anyhow::Error
The file `{}` appears to be a TOML file, but constraints mus
Error message
The file `{}` appears to be a 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:143) when the constraints path has a .toml extension (case-insensitive) but its name is not one of the specially-handled files (pyproject.toml/setup.py/setup.cfg are caught earlier, pylock by error 40). uv only parses constraints in requirements.txt format, so any other TOML file is rejected before parsing.
Source
Thrown at crates/uv-requirements/src/sources.rs:143
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("-") {
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 overrides must be specified in `requirements.txt` format",
path.user_display(),View on GitHub (pinned to f1a42680ff)
Solutions
- Convert the TOML to a flat requirements.txt-format file (`flask>=1.0` per line) and pass that to --constraints
- If the TOML is a pyproject.toml you want to constrain by, extract the dependency lists into a .txt file (e.g. `uv export -o constraints.txt` from that project)
- Check for a typo in the constraints path — the intended constraints.txt may have been misnamed
Example fix
# before uv pip install --constraints deps.toml flask # after # deps.txt: each line like `flask>=1.0` uv pip install --constraints deps.txt flask
Defensive patterns
Strategy: validation
Validate before calling
fn acceptable_constraint_path(path: &Path) -> bool {
path == Path::new("-")
|| path
.extension()
.map(|ext| !ext.eq_ignore_ascii_case("toml"))
.unwrap_or(true)
}
if !acceptable_constraint_path(&path) {
// convert to requirements.txt format before passing to uv
} Try / catch
match RequirementsSource::from_constraints_txt(path) {
Err(err) if err.to_string().contains("TOML file") => {
eprintln!("constraints must be requirements.txt format; got {path:?}");
continue;
}
source => source?,
} Prevention
- Keep constraints in plain .txt files with one PEP 508 requirement per line
- Lint CI scripts to reject --constraints/--override arguments ending in .toml
- Generate constraints via `uv export` rather than hand-edited TOML
When it happens
Trigger: Running `uv pip install --constraints Cargo.toml`, `uv pip install --constraints deps.toml`, or `--constraints CONSTRAINTS.TOML`; any call to from_constraints_txt with a path whose extension equals toml ignoring case.
Common situations: Users keep dependency pins in a custom TOML file and assume uv reads arbitrary TOML; copy-pasting a `--constraint pyproject.toml` invocation from another tool's docs; configuration management tools generating .toml constraint artifacts.
Related errors
- The file `{}` appears to be a `pylock.toml` file, but constr
- The file `{}` appears to be a TOML file, but overrides must
- The file `{}` appears to be a `{}` file, but overrides must
- The file `{}` appears to be a `pylock.toml` file, but overri
- Cannot specify constraints with a `pylock.toml` file
AI-assisted analysis of astral-sh/uv@f1a42680ff (2026-08-16).
Data as JSON: /api/errors/bad0063a988614bf.
Report an issue: GitHub.