{"id":"d6e3b9ab00c72249","repo":"python-poetry/poetry","slug":"no-valid-distribution-links-found-for-package-d","errorCode":null,"errorMessage":"No valid distribution links found for package: \"{data.name}\" version: \"{data.version}\"","messagePattern":"No valid distribution links found for package: \"(.+?)\" version: \"(.+?)\"","errorType":"exception","errorClass":"PackageNotFoundError","httpStatus":null,"severity":"error","filePath":"src/poetry/repositories/http_repository.py","lineNumber":445,"sourceCode":"\n            if universal_python2_wheel:\n                return self._get_info_from_metadata(\n                    universal_python2_wheel\n                ) or self._get_info_from_wheel(universal_python2_wheel)\n\n            if platform_specific_wheels:\n                first_wheel = platform_specific_wheels[0]\n                return self._get_info_from_metadata(\n                    first_wheel\n                ) or self._get_info_from_wheel(first_wheel)\n\n        return self._get_info_from_metadata(sdists[0]) or self._get_info_from_sdist(\n            sdists[0]\n        )\n\n    def _links_to_data(self, links: list[Link], data: PackageInfo) -> dict[str, Any]:\n        if not links:\n            raise PackageNotFoundError(\n                f'No valid distribution links found for package: \"{data.name}\" version:'\n                f' \"{data.version}\"'\n            )\n\n        files: list[PackageFile] = []\n        for link in links:\n            if link.yanked and not data.yanked:\n                # drop yanked files unless the entire release is yanked\n                continue\n\n            file_hash: str | None\n            for hash_name in (\"sha512\", \"sha384\", \"sha256\"):\n                if hash_name in link.hashes:\n                    file_hash = f\"{hash_name}:{link.hashes[hash_name]}\"\n                    break\n            else:\n                file_hash = self.calculate_sha256(link)\n","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/python-poetry/poetry/blob/92b74dcfe348d0e01e14d40d6c1fa47a4ee04a54/src/poetry/repositories/http_repository.py#L427-L463","documentation":"Raised by HTTPRepository._links_to_data when the list of distribution links for a package version is empty (http_repository.py:443-448). It means the repository's simple index page for that release contained no usable distribution files (wheels or sdists). The release may be all-yanked (and the release itself not marked yanked), deleted, or the index is malformed.","triggerScenarios":"Calling repository.package(name, version) (during lock/install) for a release whose simple-index page lists zero files; a release where every file is yanked while data.yanked is False (http_repository.py:452-454 skips them).","commonSituations":"A release was deleted from a private index but metadata still references it; all files of a release were yanked on PyPI; a custom index returns a valid HTML/JSON page with an empty file list.","solutions":["Open the package's simple index page in a browser/curl and confirm whether files exist for that version.","If the release is yanked, choose a different (non-yanked) version in your constraint.","If using a private index, re-publish or fix the release so it exposes at least one sdist/wheel.","Pin to a known-good version that has published files."],"exampleFix":"// before\n[tool.poetry.dependencies]\nbrokenpkg = \"==1.4.0\"   # 1.4.0 has no files / all yanked\n// after\n[tool.poetry.dependencies]\nbrokenpkg = \"==1.3.2\"   # a version with valid distribution files","handlingStrategy":"validation","validationCode":"release_files = repository.find_links_for_package(Package(name, version))\nif not release_files:\n    raise ValueError(f\"{name} {version} has no distribution files; pick another version\")\ndata = repository.package(name, version)","typeGuard":null,"tryCatchPattern":"from poetry.repositories.exceptions import PackageNotFoundError\ntry:\n    data = repository.package(name, version)\nexcept PackageNotFoundError as e:\n    if \"No valid distribution links\" in str(e):\n        log.warning(\"release %s %s has no files; skipping\", name, version)\n    raise","preventionTips":["Avoid pinning to yanked or just-deleted releases.","On private indexes, ensure every published release exposes at least one sdist or wheel.","Periodically audit pyproject.toml pins against the live index."],"tags":["repository","distribution","package-not-found","yanked"],"analyzedSha":"92b74dcfe348d0e01e14d40d6c1fa47a4ee04a54","analyzedAt":"2026-08-04T20:33:34.072Z","schemaVersion":2}