{"record":{"id":"d2c1bbc06878c2b4","repo":"jdx/mise","slug":"uv-graph-locking-requires-a-pypi-package","errorCode":null,"errorMessage":"uv graph locking requires a PyPI package","messagePattern":"uv graph locking requires a PyPI package","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/backend/pipx/lock.rs","lineNumber":166,"sourceCode":"    pub(crate) async fn bind_uv_python(\n        &self,\n        config: &Arc<Config>,\n        tv: &mut ToolVersion,\n    ) -> Result<()> {\n        let python = self.spawnable_dependency(config, None, \"python\").await\n            .ok_or_else(|| eyre!(\"Python graph installs require an installed interpreter; run `mise install python`\"))?;\n        let identity = if let Some(identity) = self.configured_python_identity(config).await {\n            identity\n        } else {\n            CmdLineRunner::new(&python).args([\"-I\", \"-c\", \"import sys, sysconfig; print((sys.implementation.name, sys.version_info[:2], sysconfig.get_config_var('SOABI'), sysconfig.get_platform()))\"]).read().await?.trim().to_owned()\n        };\n        tv.uv_python = Some((python, identity));\n        Ok(())\n    }\n\n    fn lock_requirement(&self, tv: &ToolVersion) -> Result<String> {\n        let PipxRequest::Pypi(package) = self.tool_name().parse()? else {\n            bail!(\"uv graph locking requires a PyPI package\");\n        };\n        let raw = tv.request.options();\n        let opts = PipxOptions::new(&raw);\n        Ok(format!(\n            \"{package}{}=={}\",\n            opts.extras().map(|v| format!(\"[{v}]\")).unwrap_or_default(),\n            tv.version\n        ))\n    }\n\n    fn lock_requirements(&self, tv: &ToolVersion) -> Result<Vec<String>> {\n        let raw = tv.request.options();\n        let opts = PipxOptions::new(&raw);\n        let mut requirements = vec![self.lock_requirement(tv)?];\n        requirements.extend(opts.with()?);\n        requirements.extend(opts.expose()?);\n        Ok(requirements)\n    }","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/backend/pipx/lock.rs#L148-L184","documentation":"uv graph locking in the pipx backend only supports lockfiles rooted at a PyPI package. lock_requirement parses the tool name as a PipxRequest and, unless it is the Pypi variant, bails: there is no package name to pin `==version` against for uv's resolution graph.","triggerScenarios":"Thrown from lock_requirement when the tool_name parses to a non-Pypi PipxRequest (e.g. a bare executable/uvx-style tool or a local path tool) while a uv dependency lock is being built or replayed via resolve_uv_lock/install_uv_lock.","commonSituations":"A user tries to lock a tool that is not a plain PyPI package (e.g. `pipx:github:some/repo` style or a locally referenced tool) with dependency locking enabled; config misuses the pypi lock feature for non-registry tools.","solutions":["Reference the tool as a PyPI package so it parses as PipxRequest::Pypi (e.g. `pipx:ruff` rather than a path/git form).","Disable uv dependency locking for this tool (set the uvx-disable option or `[settings.pypi] uvx = false`) if locking is not required.","Install the tool through a different backend suited to non-PyPI sources (aqua, github, etc.)."],"exampleFix":"// before (non-PyPI source, cannot be uv-locked)\n[tools]\nmytool = \"pipx:github:org/mytool\"\n\n// after (PyPI package, lockable)\n[tools]\nmytool = \"pipx:mytool\"","handlingStrategy":"validation","validationCode":"if (!/^pipx:[a-z0-9_.-]+$/i.test(toolRef)) console.warn('uv locking requires a plain PyPI package reference');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only reference PyPI-published names for pipx tools you want locked","Use git/path sources through other backends instead of pipx","Disable uv locking explicitly for non-registry tools"],"tags":["python","uv","pypi","unsupported-operation"],"backgroundTag":"unsupported-operation","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"}