{"record":{"id":"bef2c79cf1f2d1e4","repo":"jdx/mise","slug":"package-requires-consistent-python-metadata-on-published","errorCode":null,"errorMessage":"package {} requires consistent Python metadata on published wheels to generate a portable lock","messagePattern":"package (.+?) requires consistent Python metadata on published wheels to generate a portable lock","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/backend/pipx/lock.rs","lineNumber":603,"sourceCode":"        if PIPXBackend::version_from_distribution_filename(package, &filename).as_deref()\n            == Some(version)\n            && filename.ends_with(\".whl\")\n        {\n            let value = python\n                .captures(link.as_str())\n                .and_then(|c| c.get(1))\n                .map(|v| v.as_str())\n                .unwrap_or(\"\");\n            constraints.insert(\n                value\n                    .replace(\"&gt;\", \">\")\n                    .replace(\"&lt;\", \"<\")\n                    .replace(\"&amp;\", \"&\"),\n            );\n        }\n    }\n    if constraints.len() != 1 {\n        bail!(\n            \"package {} requires consistent Python metadata on published wheels to generate a portable lock\",\n            package\n        );\n    }\n    Ok(constraints.into_iter().next().unwrap())\n}\n\nfn uv_index_url(registry: &str) -> Result<String> {\n    let base = registry.split(\"{}\").next().unwrap_or(registry);\n    let mut url = url::Url::parse(base)?;\n    if url\n        .host_str()\n        .is_some_and(|host| host == \"pypi.org\" || host.ends_with(\".pypi.org\"))\n    {\n        url.set_path(\"/simple/\");\n    } else {\n        let path = url.path().trim_end_matches('/').trim_end_matches(\"/simple\");\n        url.set_path(&format!(\"{path}/simple/\"));","sourceCodeStart":585,"sourceCodeEnd":621,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/backend/pipx/lock.rs#L585-L621","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (mise.toml)\n[tools]\nblack = \"latest\"\n// after\n[tools]\nblack = \"24.8.0\" # pinned to a release with consistent wheel metadata","handlingStrategy":"validation","validationCode":"# check wheel metadata consistency before locking\npython -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","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["python","pipx","lockfile","metadata"],"backgroundTag":"schema-validation-failed","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}