{"id":"7ca274853da48649","repo":"python-poetry/poetry","slug":"extra-extra-is-not-specified","errorCode":null,"errorMessage":"Extra [{extra}] is not specified.","messagePattern":"Extra \\[(.+?)\\] is not specified\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/poetry/installation/installer.py","lineNumber":190,"sourceCode":"        return self\n\n    def whitelist(self, packages: Iterable[str]) -> Installer:\n        self._whitelist = [canonicalize_name(p) for p in packages]\n\n        return self\n\n    def extras(self, extras: list[str]) -> Installer:\n        self._extras = [canonicalize_name(extra) for extra in extras]\n\n        return self\n\n    def _do_refresh(self) -> int:\n        from poetry.puzzle.solver import Solver\n\n        # Checking extras\n        for extra in self._extras:\n            if extra not in self._package.extras:\n                raise ValueError(f\"Extra [{extra}] is not specified.\")\n\n        locked_repository = self._locker.locked_repository()\n        solver = Solver(\n            self._package,\n            self._pool,\n            locked_repository.packages,\n            locked_repository.packages,\n            self._io,\n        )\n\n        # Always re-solve directory dependencies, otherwise we can't determine\n        # if anything has changed (and the lock file contains an invalid version).\n        use_latest = [\n            p.name for p in locked_repository.packages if p.source_type == \"directory\"\n        ]\n\n        with solver.provider.use_source_root(\n            source_root=self._env.path.joinpath(\"src\")","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/python-poetry/poetry/blob/92b74dcfe348d0e01e14d40d6c1fa47a4ee04a54/src/poetry/installation/installer.py#L172-L208","documentation":"Raised by Installer._do_refresh at src/poetry/installation/installer.py:188-190 when an --extras value passed to `poetry install` does not correspond to any extra defined on the root project (self._package.extras). ValueError. The refresh path re-resolves the existing lock.","triggerScenarios":"Running `poetry install --refresh --extras foo` where 'foo' is not declared under [tool.poetry.extras] in pyproject.toml. The check canonicalizes the requested extra and looks it up in the project's extras mapping.","commonSituations":"Typo in the extra name, an extra that was renamed/removed from pyproject.toml, or running the command in a project that has no extras defined at all.","solutions":["List defined extras: inspect [tool.poetry.extras] in pyproject.toml.","Correct the extra name on the command line (extras are case-insensitive but must exist).","Add the missing extra to pyproject.toml if the intent is to install a new optional group."],"exampleFix":"# before\n$ poetry install --refresh --extras testng\nValueError: Extra [testng] is not specified.\n\n# fix command\n$ poetry install --refresh --extras testing\n\n# or add the extra\n[tool.poetry.extras]\ntestng = [\"pytest\"]","handlingStrategy":"validation","validationCode":"from poetry.utils.helpers import canonicalize_name\n\ndef validate_extras(requested, declared):\n    declared_set = {canonicalize_name(e) for e in declared}\n    for extra in requested:\n        if canonicalize_name(extra) not in declared_set:\n            raise ValueError(f'Extra [{canonicalize_name(extra)}] is not specified.')","typeGuard":null,"tryCatchPattern":"try:\n    installer.whitelist([pkg])  # or run()\nexcept ValueError as e:\n    if 'Extra [' in str(e):\n        # prompt user / list available extras from pyproject before retrying\n        raise SystemExit(f'Unknown extra: {e}') from e\n    raise","preventionTips":["Source the list of valid extras from pyproject.toml before scripting installs.","Lint CI scripts that pass --extras against declared extras."],"tags":["extras","installer","pyproject","validation"],"analyzedSha":"92b74dcfe348d0e01e14d40d6c1fa47a4ee04a54","analyzedAt":"2026-08-04T20:33:34.072Z","schemaVersion":2}