{"id":"5110c3c458b5094d","repo":"pypa/pip","slug":"fatal-internal-error-id-2-please-report-as-a-bu","errorCode":null,"errorMessage":"Fatal Internal error [id=2]. Please report as a bug.","messagePattern":"Fatal Internal error \\[id=2\\]\\. Please report as a bug\\.","errorType":"exception","errorClass":"ConfigurationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/configuration.py","lineNumber":381,"sourceCode":"        # virtualenv config\n        yield kinds.SITE, config_files[kinds.SITE]\n\n        if env_config_file is not None:\n            yield kinds.ENV, [env_config_file]\n        else:\n            yield kinds.ENV, []\n\n    def get_values_in_config(self, variant: Kind) -> dict[str, Any]:\n        \"\"\"Get values present in a config file\"\"\"\n        return self._config[variant]\n\n    def _get_parser_to_modify(self) -> tuple[str, RawConfigParser]:\n        # Determine which parser to modify\n        assert self.load_only\n        parsers = self._parsers[self.load_only]\n        if not parsers:\n            # This should not happen if everything works correctly.\n            raise ConfigurationError(\n                \"Fatal Internal error [id=2]. Please report as a bug.\"\n            )\n\n        # Use the highest priority parser.\n        return parsers[-1]\n\n    # XXX: This is patched in the tests.\n    def _mark_as_modified(self, fname: str, parser: RawConfigParser) -> None:\n        file_parser_tuple = (fname, parser)\n        if file_parser_tuple not in self._modified_parsers:\n            self._modified_parsers.append(file_parser_tuple)\n\n    def __repr__(self) -> str:\n        return f\"{self.__class__.__name__}({self._dictionary!r})\"\n","sourceCodeStart":363,"sourceCodeEnd":396,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/configuration.py#L363-L396","documentation":"A defensive assertion-style ConfigurationError raised in _get_parser_to_modify() when load_only is set but no parser has been registered for that configuration kind. The code itself says 'This should not happen if everything works correctly', so hitting it indicates an internal state inconsistency rather than user config misuse. It is explicitly a bug-report prompt.","triggerScenarios":"Reached only if a code path calls a mutating config operation (set_value/save/etc.) with self.load_only set to a Kind for which self._parsers[load_only] is empty - i.e. load_only was assigned without ever successfully calling load() for that variant. In normal pip use this is unreachable; it appears in tests or programmatic misuse of the Configuration API.","commonSituations":"Programmatically constructing a Configuration, setting load_only without calling load(), then calling set_value/save; a third-party tool vendoring pip internals and calling _get_parser_to_modify out of order; a regression in pip's own config subcommand.","solutions":["Report it as a bug upstream with the exact pip version and reproduction, since the message says so.","If calling the Configuration API programmatically, ensure load() runs for the target Kind before any mutating operation and before setting load_only.","Upgrade/downgrade pip to a version without the regression.","Use the public 'pip config set' CLI instead of internal APIs."],"exampleFix":"# before\ncfg.load_only = kinds.USER\ncfg.set_value('global.timeout', '30')\n\n# after\ncfg.load_only = kinds.USER\ncfg.load()  # populates _parsers before mutating\ncfg.set_value('global.timeout', '30')","handlingStrategy":"validation","validationCode":"def can_modify(cfg, kind) -> bool:\n    return bool(cfg._parsers.get(kind))\n# before calling cfg.set_value(...):\nassert cfg.load_only is not None and can_modify(cfg, cfg.load_only)","typeGuard":"def parser_ready(cfg) -> bool:\n    return cfg.load_only is not None and bool(cfg._parsers.get(cfg.load_only))","tryCatchPattern":"from pip._internal.exceptions import ConfigurationError\ntry:\n    cfg.set_value(key, value)\nexcept ConfigurationError as e:\n    if 'Fatal Internal error' in str(e):\n        # ensure load() ran for load_only; this is a bug\n        raise","preventionTips":["Call Configuration.load() for a Kind before setting load_only or mutating.","Prefer the public 'pip config' CLI over internal Configuration APIs.","Treat this error as a bug report, not normal operation."],"tags":["config","internal","assertion","unreachable","bug"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}