{"record":{"id":"6625caebbb65bf20","repo":"pypa/pip","slug":"absolute-paths-are-not-supported-in-pylock-files-o","errorCode":null,"errorMessage":"Absolute paths are not supported in pylock files obtained from a URL: {path!r} in {pylock_path_or_url!r}","messagePattern":"Absolute paths are not supported in pylock files obtained from a URL: (.+?) in (.+?)","errorType":"exception","errorClass":"InstallationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/utils/pylock.py","lineNumber":179,"sourceCode":"                # \"file:...\" as absolute, so it reaches here and urljoin honors\n                # its scheme, discarding the pylock base. Only keep the result\n                # if its scheme and host still match the lock's own.\n                base = urlsplit(pylock_path_or_url)\n                target = urlsplit(dist_url)\n                if (target.scheme, target.netloc) != (base.scheme, base.netloc):\n                    raise InstallationError(\n                        f\"Path {path!r} in pylock file obtained from a URL \"\n                        f\"resolves outside its location: {pylock_path_or_url!r}\"\n                    )\n                return dist_url\n            else:\n                return path_to_url(\n                    os.path.join(os.path.dirname(pylock_path_or_url), path)\n                )\n        else:\n            # absolute path, reject if pylock comes from a URL\n            if _is_url(pylock_path_or_url):\n                raise InstallationError(\n                    f\"Absolute paths are not supported in pylock files obtained \"\n                    f\"from a URL: {path!r} in {pylock_path_or_url!r}\"\n                )\n            return path_to_url(path)\n    else:\n        assert url is not None  # guaranteed by packaging.pylock validation\n        return url\n\n\ndef package_vcs_requirement_url(\n    pylock_path_or_url: str, package_vcs: PackageVcs\n) -> str:\n    dist_url = _package_dist_url(pylock_path_or_url, package_vcs.path, package_vcs.url)\n    url = f\"{package_vcs.type}+{dist_url}@{package_vcs.commit_id}\"\n    if package_vcs.subdirectory:\n        if \"#\" in url:\n            raise InstallationError(\n                f\"Package URL {url!r} cannot contain fragments in combination \"","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/utils/pylock.py#L161-L197","documentation":"Raised as InstallationError by _package_dist_url (pylock.py:179) when a pylock file loaded from a URL contains an absolute filesystem path in a package's path field. Absolute paths in a remote lock file are a security risk: they could reference arbitrary local files on the machine running pip (e.g. /etc/shadow). The code checks _is_url(pylock_path_or_url) at line 178 and rejects absolute paths at 179. Local (non-URL) pylock files are allowed to use absolute paths.","triggerScenarios":"Loading a pylock.toml from http(s):// or file:// URL that has a package entry with path=\"/some/abs/path\" or path=\"C:\\\\path\". The os.path.isabs check at line 156 passes, then the URL check at 178 triggers the raise.","commonSituations":"A lock file generated on one machine that embedded absolute build paths and is then distributed via a URL. Lock files created by a CI system that recorded container/runner absolute paths. Copying a local lock file to a web server without sanitising paths.","solutions":["Use relative paths in the pylock file so they resolve against the lock file's URL base.","If you control the packages, set the url field (a proper download URL) instead of the path field for remote lock files.","Download the pylock file and use it from a local path instead of a URL, which allows absolute paths.","Regenerate the lock file from scratch on the target system so paths are local and relative."],"exampleFix":"// before (remote pylock.toml)\n[[packages]]\nname = \"pkg\"\npath = \"/home/user/wheels/pkg.whl\"\n\n// after (remote pylock.toml)\n[[packages]]\nname = \"pkg\"\nurl = \"https://index.example.com/wheels/pkg.whl\"","handlingStrategy":"validation","validationCode":"import os\n\ndef find_absolute_paths_in_remote_pylock(toml_content: str, is_url: bool) -> list[str]:\n    \"\"\"Find absolute paths in a pylock file loaded from a URL.\"\"\"\n    if not is_url:\n        return []  # local pylock files allow absolute paths\n    import re\n    # Naive check for path = \"/abs/path\" patterns\n    return re.findall(r'path\\s*=\\s*[\"\\']?(/[^\"\\']+)[\"\\']?', toml_content)","typeGuard":"import os\n\ndef is_safe_pylock_path_field(path: str, pylock_is_url: bool) -> bool:\n    \"\"\"True if the path field is safe given the lock file source.\"\"\"\n    if os.path.isabs(path):\n        return not pylock_is_url  # absolute paths only OK for local lock files\n    return True","tryCatchPattern":null,"preventionTips":["Never use absolute filesystem paths in pylock files intended for remote distribution.","Use the url field (downloadable URL) instead of path for remote lock files.","Lint lock files for absolute paths before publishing them to a URL."],"tags":["pylock","absolute-path","security","remote-lock","url"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}