{"id":"04f68b52b67724d0","repo":"python-poetry/poetry","slug":"unable-to-find-a-suitable-destination-for-path","errorCode":null,"errorMessage":"Unable to find a suitable destination for \"{path}\" in {paths_csv(self._candidates)}","messagePattern":"Unable to find a suitable destination for \"(.+?)\" in (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/poetry/utils/env/site_packages.py","lineNumber":90,"sourceCode":"\n    def make_candidates(\n        self, path: Path, writable_only: bool = False, strict: bool = False\n    ) -> list[Path]:\n        candidates = self._candidates if not writable_only else self.writable_candidates\n        if path.is_absolute():\n            for candidate in candidates:\n                with contextlib.suppress(ValueError):\n                    path.relative_to(candidate)\n                    return [path]\n            site_type = \"writable \" if writable_only else \"\"\n            raise ValueError(\n                f\"{path} is not relative to any discovered {site_type}sites\"\n            )\n\n        results = [candidate / path for candidate in candidates]\n\n        if not results and strict:\n            raise RuntimeError(\n                f'Unable to find a suitable destination for \"{path}\" in'\n                f\" {paths_csv(self._candidates)}\"\n            )\n\n        return results\n\n    def distributions(\n        self, name: str | None = None, writable_only: bool = False\n    ) -> Iterable[metadata.Distribution]:\n        path = list(\n            map(\n                str, self._candidates if not writable_only else self.writable_candidates\n            )\n        )\n\n        yield from metadata.PathDistribution.discover(name=name, path=path)\n\n    def find_distribution(","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/python-poetry/poetry/blob/92b74dcfe348d0e01e14d40d6c1fa47a4ee04a54/src/poetry/utils/env/site_packages.py#L72-L108","documentation":"Raised as RuntimeError in SitePackages.make_candidates when strict=True, the path is relative, but the computed candidate list (candidate / path for each) is empty - i.e. there are no site directories to resolve the relative path against.","triggerScenarios":"Calling make_candidates(path, strict=True) (directly or via _path_method_wrapper, which always sets strict=True) with a relative path when self._candidates is empty, so results=[]. Exact branch: site_packages.py:87-93.","commonSituations":"A SitePackages instance constructed with empty/missing purelib and platlib (broken env discovery); the env has no detectable site-packages directories; operating on a freshly created or partially-initialized env object.","solutions":["Verify the Env actually has site-packages: check env.site_packages.candidates is non-empty.","Recreate or reload the env so purelib/platlib are discovered correctly.","Construct the SitePackages with explicit, existing purelib/platlib paths.","Avoid passing strict=True on an env you haven't confirmed has sites."],"exampleFix":"// before - SitePackages with no candidates\nsp = SitePackages(purelib=Path(\"/does/not/exist\"))\nsp.write_text(Path(\"foo.py\"), \"\")  # -> RuntimeError (strict, empty)\n\n// after\nsp = SitePackages(purelib=env.site_packages.purelib)\nsp.write_text(Path(\"foo.py\"), \"\")","handlingStrategy":"validation","validationCode":"def site_packages_has_candidates(site_packages) -> bool:\n    return len(site_packages.candidates) > 0 and all(p.exists() for p in site_packages.candidates)","typeGuard":"def is_no_destination_runtime_error(e: Exception) -> bool:\n    return isinstance(e, RuntimeError) and \"Unable to find a suitable destination\" in str(e)","tryCatchPattern":"try:\n    site_packages._path_method_wrapper(rel_path, \"write_text\", data)\nexcept RuntimeError as e:\n    if \"Unable to find a suitable destination\" in str(e):\n        # reload env / fix SitePackages construction first\n        site_packages = reload_site_packages(env)\n        site_packages.write_text(rel_path, data)\n    else:\n        raise","preventionTips":["Confirm site_packages.candidates is non-empty before calling path methods.","Construct SitePackages with an existing purelib/platlib from a valid Env.","Reload the env if it was created/modified after the SitePackages was built.","Avoid strict=True on an env whose site directories have not been discovered."],"tags":["site-packages","empty-candidates","strict","filesystem"],"analyzedSha":"92b74dcfe348d0e01e14d40d6c1fa47a4ee04a54","analyzedAt":"2026-08-04T20:33:34.072Z","schemaVersion":2}