{"record":{"id":"ef293d4e028b19a3","repo":"pytest-dev/pytest","slug":"alias-r-is-already-an-alias-of-already-r","errorCode":null,"errorMessage":"{alias!r} is already an alias of {already!r}","messagePattern":"(.+?) is already an alias of (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/config/argparsing.py","lineNumber":364,"sourceCode":"            ini_type = _ini_type_to_member(name, type)\n        if default is NOTSET:\n            if isinstance(ini_type, (tuple, _IniLiteral)):\n                kind = \"union\" if isinstance(ini_type, tuple) else \"Literal\"\n                raise ValueError(\n                    f\"ini option {name!r} has a {kind} type, which has no \"\n                    \"implicit default; pass an explicit `default` to `addini`\"\n                )\n            default = get_ini_default_for_type(ini_type)\n\n        self._inidict[name] = (help, ini_type, default)\n\n        for alias in aliases:\n            if alias in self._inidict:\n                raise ValueError(\n                    f\"alias {alias!r} conflicts with existing configuration option\"\n                )\n            if (already := self._ini_aliases.get(alias)) is not None:\n                raise ValueError(f\"{alias!r} is already an alias of {already!r}\")\n            self._ini_aliases[alias] = name\n\n\ndef get_ini_default_for_type(type: _IniTypeTag) -> Any:\n    \"\"\"\n    Used by addini to get the default value for a given config option type, when\n    default is not supplied.\n    \"\"\"\n    if type in (\"paths\", \"pathlist\", \"args\", \"linelist\"):\n        return []\n    elif type == \"bool\":\n        return False\n    elif type == \"int\":\n        return 0\n    elif type == \"float\":\n        return 0.0\n    else:\n        return \"\"","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/pytest-dev/pytest/blob/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/config/argparsing.py#L346-L382","documentation":"Raised during addini() when an alias in the aliases= list was already registered as an alias of another option. Each alias string can map to only one canonical option. The check `(already := self._ini_aliases.get(alias)) is not None` finds a prior mapping.","triggerScenarios":"Calling parser.addini('opt_b', aliases=['shared']) when 'shared' was already used as an alias for 'opt_a' in a prior addini call. The alias key already exists in self._ini_aliases.","commonSituations":"Two plugins independently choosing the same alias string. Refactoring and forgetting an old alias registration. Copy-pasting addini calls with shared alias values.","solutions":["Use a unique alias not already claimed by another option","Remove the duplicate alias from the earlier addini call if it is no longer needed","Inspect self._ini_aliases before registering to find available aliases"],"exampleFix":"# before\nparser.addini('opt_a', type='string', aliases=['shared'])\nparser.addini('opt_b', type='string', aliases=['shared'])\n\n# after\nparser.addini('opt_a', type='string', aliases=['shared'])\nparser.addini('opt_b', type='string', aliases=['shared_b'])","handlingStrategy":"validation","validationCode":"def check_alias_not_taken(parser, aliases: list[str]) -> dict[str, str]:\n    taken = {a: parser._ini_aliases[a] for a in aliases if a in parser._ini_aliases}\n    return taken\n# Usage: taken = check_alias_not_taken(parser, ['shared'])","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure each alias string is unique across all addini calls","Inspect parser._ini_aliases before registering to find available aliases","Namespace aliases with a plugin prefix to avoid collisions: 'mypkg_opt'"],"tags":["pytest","config","addini","alias","naming-conflict","plugin-api"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}