jdx/mise · error
package requires consistent Python metadata on published…
Error message
package {} requires consistent Python metadata on published wheels to generate a portable lock What it means
mise's pipx backend builds a portable lockfile by deriving a single version constraint from the Python package metadata published on wheels. This error is thrown by simple_index_python_requirement when the metadata does not converge to exactly one consistent constraint — the wheel set provides zero or multiple differing constraints — so no deterministic, portable lock can be produced.
Solutions
- Pin the package to a version whose published wheels carry one consistent Python requirement constraint
- Check the package's PyPI metadata (Requires-Python across its wheels) and pick a release with uniform metadata
- Regenerate the lock after upgrading/reinstalling the package so fresh metadata is fetched
Example fix
// before (mise.toml) [tools] black = "latest" // after [tools] black = "24.8.0" # pinned to a release with consistent wheel metadata
Defensive patterns
Strategy: validation
Validate before calling
# check wheel metadata consistency before locking
python -c "import json,urllib.request as u;d=json.load(u.urlopen('https://pypi.org/pypi/black/json'));print({v['requires_python'] for v in d['releases'].values() for v in []})" # or inspect dist metadata: all Requires-Python values must be identical Prevention
- Pin package versions with known-consistent wheel metadata instead of 'latest'
- Inspect PyPI Requires-Python fields across the package's releases before locking
- Regenerate locks after upstream releases rather than trusting stale metadata
When it happens
Trigger: Locking a pipx-managed Python package whose published wheels expose inconsistent or missing 'Requires-Python'-style constraint metadata, such that the collected constraints list has a length other than 1. Reached via release_python_requirement during lock generation.
Common situations: Locking a package whose maintainers publish wheels with divergent Python requirement strings across versions/platforms; very new or niche packages with sloppy packaging metadata; a package that recently changed its Python version bounds between releases.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- dependency locking does not support uvx_args or pipx_args
- has a uv dependency graph; use uv with a PyPI package to…
- has no uv dependency graph; run `mise lock
- has a wheel without a SHA256 hash
- pipx is required to install
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/bef2c79cf1f2d1e4.
Report an issue: GitHub.
Appendix: source
Thrown at src/backend/pipx/lock.rs:603
if PIPXBackend::version_from_distribution_filename(package, &filename).as_deref()
== Some(version)
&& filename.ends_with(".whl")
{
let value = python
.captures(link.as_str())
.and_then(|c| c.get(1))
.map(|v| v.as_str())
.unwrap_or("");
constraints.insert(
value
.replace(">", ">")
.replace("<", "<")
.replace("&", "&"),
);
}
}
if constraints.len() != 1 {
bail!(
"package {} requires consistent Python metadata on published wheels to generate a portable lock",
package
);
}
Ok(constraints.into_iter().next().unwrap())
}
fn uv_index_url(registry: &str) -> Result<String> {
let base = registry.split("{}").next().unwrap_or(registry);
let mut url = url::Url::parse(base)?;
if url
.host_str()
.is_some_and(|host| host == "pypi.org" || host.ends_with(".pypi.org"))
{
url.set_path("/simple/");
} else {
let path = url.path().trim_end_matches('/').trim_end_matches("/simple");
url.set_path(&format!("{path}/simple/"));View on GitHub (pinned to 533346cc37)