{"id":"86d28b0d435c4a90","repo":"pytest-dev/pytest","slug":"ini-option-name-r-has-a-kind-type-which-has-n","errorCode":null,"errorMessage":"ini option {name!r} has a {kind} type, which has no implicit default; pass an explicit `default` to `addini`","messagePattern":"ini option (.+?) has a (.+?) type, which has no implicit default; pass an explicit `default` to `addini`","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/config/argparsing.py","lineNumber":350,"sourceCode":"            .. versionadded:: 9.0\n                The ``aliases`` parameter.\n\n        The value of configuration keys can be retrieved via a call to\n        :py:func:`config.getini(name) <pytest.Config.getini>`.\n        \"\"\"\n        ini_type: IniType\n        if type is None:\n            ini_type = \"string\"\n        elif get_origin(type) in (Union, types.UnionType):\n            ini_type = tuple(\n                _ini_type_to_member(name, member) for member in get_args(type)\n            )\n        else:\n            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:","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/config/argparsing.py#L332-L368","documentation":"Raised by Parser.addini() when the type is a union (e.g. int | str) or a Literal of strings, but no explicit default= argument was provided. These compound types have no single sensible implicit default, so pytest refuses to guess and requires the plugin author to pass one.","triggerScenarios":"Calling parser.addini('myopt', type=int | str) or parser.addini('mode', type=Literal['a','b']) without a default= keyword. The check at line 347-353 sees default is NOTSET and ini_type is a tuple or _IniLiteral.","commonSituations":"Adding a new Literal/union ini option and forgetting the default; refactoring a simple-typed option into a union without adding a default.","solutions":["Pass an explicit default: parser.addini('mode', type=Literal['a','b'], default='a').","Choose a default that matches one of the union members / Literal choices.","If you want a None default, pass default=None explicitly."],"exampleFix":"# before\nparser.addini('mode', type=Literal['fast','slow'], help='run mode')\n\n# after\nparser.addini('mode', type=Literal['fast','slow'], default='fast', help='run mode')","handlingStrategy":"validation","validationCode":"from typing import get_origin, get_args, Literal, Union, types\ndef needs_default(type_: object) -> bool:\n    if get_origin(type_) in (Union, types.UnionType):\n        return True\n    if get_origin(type_) is Literal:\n        return True\n    return False\n# enforce: always pass default= when needs_default(type_) is True","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass an explicit default= when using union or Literal ini types.","Add a registration smoke test in CI to catch missing defaults early."],"tags":["pytest","plugin","config","addini","literal","union","default"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}