{"record":{"id":"fa53dd1f0c57a85f","repo":"pypa/pip","slug":"can-t-change-extraction-path-files-already-extrac","errorCode":null,"errorMessage":"Can't change extraction path, files already extracted","messagePattern":"Can't change extraction path, files already extracted","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/pkg_resources/__init__.py","lineNumber":1507,"sourceCode":"\n        If you do not call this routine before any extractions take place, the\n        path defaults to the return value of ``get_default_cache()``.  (Which\n        is based on the ``PYTHON_EGG_CACHE`` environment variable, with various\n        platform-specific fallbacks.  See that routine's documentation for more\n        details.)\n\n        Resources are extracted to subdirectories of this path based upon\n        information given by the ``IResourceProvider``.  You may set this to a\n        temporary directory, but then you must call ``cleanup_resources()`` to\n        delete the extracted files when done.  There is no guarantee that\n        ``cleanup_resources()`` will be able to remove all extracted files.\n\n        (Note: you may not change the extraction path for a given resource\n        manager once resources have been extracted, unless you first call\n        ``cleanup_resources()``.)\n        \"\"\"\n        if self.cached_files:\n            raise ValueError(\"Can't change extraction path, files already extracted\")\n\n        self.extraction_path = path\n\n    def cleanup_resources(self, force: bool = False) -> list[str]:\n        \"\"\"\n        Delete all extracted resource files and directories, returning a list\n        of the file and directory names that could not be successfully removed.\n        This function does not have any concurrency protection, so it should\n        generally only be called when the extraction path is a temporary\n        directory exclusive to a single process.  This method is not\n        automatically called; you must call it explicitly or register it as an\n        ``atexit`` function if you wish to ensure cleanup of a temporary\n        directory used for extractions.\n        \"\"\"\n        # XXX\n        return []\n\n","sourceCodeStart":1489,"sourceCodeEnd":1525,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/pkg_resources/__init__.py#L1489-L1525","documentation":"Raised by ResourceManager.set_extraction_path() when resources have already been extracted (cached_files is non-empty). Once files exist on disk under the current extraction path, the path cannot be changed because existing extracted files would be orphaned. You must call cleanup_resources() first.","triggerScenarios":"Calling set_extraction_path(new_path) after resource_filename() or another extraction has already occurred in the same ResourceManager instance.","commonSituations":"Calling set_extraction_path() too late in a long-running process; reconfiguring the egg cache after zip-based resources were already unpacked.","solutions":["Call cleanup_resources() before set_extraction_path() to clear cached files.","Set the extraction path at process startup, before any resource extraction occurs.","Set the PYTHON_EGG_CACHE environment variable before interpreter start to avoid needing set_extraction_path() entirely."],"exampleFix":"// before\n# after extractions happened\nmanager.set_extraction_path(new_dir)  # raises\n// after\nmanager.cleanup_resources()\nmanager.set_extraction_path(new_dir)","handlingStrategy":"validation","validationCode":"if manager.cached_files:\n    manager.cleanup_resources()\nmanager.set_extraction_path(new_path)","typeGuard":null,"tryCatchPattern":"try:\n    manager.set_extraction_path(path)\nexcept ValueError:\n    manager.cleanup_resources()\n    manager.set_extraction_path(path)","preventionTips":["Set extraction path before any resource access.","Set PYTHON_EGG_CACHE env var at process start instead."],"tags":["pkg-resources","resources","extraction","state-error"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}