pytest-dev/pytest · error · ValueError
is already an alias of
Error message
{alias!r} is already an alias of {already!r} What it means
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.
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
Example fix
# before
parser.addini('opt_a', type='string', aliases=['shared'])
parser.addini('opt_b', type='string', aliases=['shared'])
# after
parser.addini('opt_a', type='string', aliases=['shared'])
parser.addini('opt_b', type='string', aliases=['shared_b']) Defensive patterns
Strategy: validation
Validate before calling
def check_alias_not_taken(parser, aliases: list[str]) -> dict[str, str]:
taken = {a: parser._ini_aliases[a] for a in aliases if a in parser._ini_aliases}
return taken
# Usage: taken = check_alias_not_taken(parser, ['shared']) Prevention
- 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'
When it happens
Trigger: 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.
Common situations: Two plugins independently choosing the same alias string. Refactoring and forgetting an old alias registration. Copy-pasting addini calls with shared alias values.
Related errors
- alias conflicts with existing configuration option
- ini option has a type, which has no implicit default; pass…
- invalid type for ini option
- invalid type for ini option
- option names already added
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/ef293d4e028b19a3.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/config/argparsing.py:364
ini_type = _ini_type_to_member(name, type)
if default is NOTSET:
if isinstance(ini_type, (tuple, _IniLiteral)):
kind = "union" if isinstance(ini_type, tuple) else "Literal"
raise ValueError(
f"ini option {name!r} has a {kind} type, which has no "
"implicit default; pass an explicit `default` to `addini`"
)
default = get_ini_default_for_type(ini_type)
self._inidict[name] = (help, ini_type, default)
for alias in aliases:
if alias in self._inidict:
raise ValueError(
f"alias {alias!r} conflicts with existing configuration option"
)
if (already := self._ini_aliases.get(alias)) is not None:
raise ValueError(f"{alias!r} is already an alias of {already!r}")
self._ini_aliases[alias] = name
def get_ini_default_for_type(type: _IniTypeTag) -> Any:
"""
Used by addini to get the default value for a given config option type, when
default is not supplied.
"""
if type in ("paths", "pathlist", "args", "linelist"):
return []
elif type == "bool":
return False
elif type == "int":
return 0
elif type == "float":
return 0.0
else:
return ""View on GitHub (pinned to 0d6fbdeffa)