{"id":"d1068abdae694a2d","repo":"pypa/pip","slug":"script-script-r-not-found-in-metadata-at-self-e","errorCode":null,"errorMessage":"Script {script!r} not found in metadata at {self.egg_info!r}","messagePattern":"Script (.+?) not found in metadata at (.+?)","errorType":"exception","errorClass":"ResolutionError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/pkg_resources/__init__.py","lineNumber":1701,"sourceCode":"\n    def resource_isdir(self, resource_name: str):\n        return self._isdir(self._fn(self.module_path, resource_name))\n\n    def metadata_isdir(self, name: str) -> bool:\n        return bool(self.egg_info and self._isdir(self._fn(self.egg_info, name)))\n\n    def resource_listdir(self, resource_name: str):\n        return self._listdir(self._fn(self.module_path, resource_name))\n\n    def metadata_listdir(self, name: str) -> list[str]:\n        if self.egg_info:\n            return self._listdir(self._fn(self.egg_info, name))\n        return []\n\n    def run_script(self, script_name: str, namespace: dict[str, Any]):\n        script = 'scripts/' + script_name\n        if not self.has_metadata(script):\n            raise ResolutionError(\n                \"Script {script!r} not found in metadata at {self.egg_info!r}\".format(\n                    **locals()\n                ),\n            )\n\n        script_text = self.get_metadata(script).replace('\\r\\n', '\\n')\n        script_text = script_text.replace('\\r', '\\n')\n        script_filename = self._fn(self.egg_info, script)\n        namespace['__file__'] = script_filename\n        if os.path.exists(script_filename):\n            source = _read_utf8_with_fallback(script_filename)\n            code = compile(source, script_filename, 'exec')\n            exec(code, namespace, namespace)\n        else:\n            from linecache import cache\n\n            cache[script_filename] = (\n                len(script_text),","sourceCodeStart":1683,"sourceCodeEnd":1719,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/pkg_resources/__init__.py#L1683-L1719","documentation":"Raised as a ResolutionError by Distribution.run_script() when the requested script_name does not correspond to an entry under EGG-INFO/scripts/ in the distribution's metadata. run_script() builds 'scripts/' + script_name and checks has_metadata(); if absent it refuses to exec. The distribution must therefore carry script files in its egg-info metadata for the name to resolve.","triggerScenarios":"Calling dist.run_script('my_script', namespace_dict) where 'my_script' is not present as EGG-INFO/scripts/my_script in that distribution's metadata (typo, wrong distribution, or scripts were never installed/packaged).","commonSituations":"Calling console-script entry points manually via run_script with the wrong name, a distribution installed without its scripts directory (stripped wheel, broken metadata), or a stale egg-info left after a version change.","solutions":["Verify the script exists first: `if dist.has_metadata('scripts/' + name): dist.run_script(name, ns)`.","List available scripts via `dist.metadata_listdir('scripts')` and use an exact name from that list.","Prefer EntryPoint.load() over run_script() for invoking console entry points, which is the modern, metadata-driven path."],"exampleFix":"// before\ndist.run_script('manage', ns)  # ResolutionError if 'scripts/manage' missing\n\n// after\nep = dist.get_entry_info('console_scripts', 'manage')\nep.load(require=False)(ns)  # use the entry point instead","handlingStrategy":"validation","validationCode":"import pkg_resources\n\ndef safe_run_script(dist, script_name, namespace):\n    script_rel = 'scripts/' + script_name\n    if dist.has_metadata(script_rel):\n        return dist.run_script(script_name, namespace)\n    available = dist.metadata_listdir('scripts') if dist.egg_info else []\n    raise KeyError(f'{script_name!r} not in scripts/; available: {available}')","typeGuard":"def script_exists(dist, script_name):\n    return dist.has_metadata('scripts/' + script_name)","tryCatchPattern":"try:\n    dist.run_script(name, ns)\nexcept pkg_resources.ResolutionError as e:\n    if 'not found in metadata' in str(e):\n        # script missing; list what is available\n        avail = dist.metadata_listdir('scripts')\n        raise KeyError(f'missing {name!r}; have {avail}') from e\n    raise","preventionTips":["Check has_metadata('scripts/' + name) before run_script().","Prefer EntryPoint.load() for invoking console entry points.","List scripts via metadata_listdir('scripts') to discover valid names."],"tags":["pkg-resources","scripts","metadata","resolution"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}