{"record":{"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/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/config/argparsing.py#L332-L368","documentation":"Raised during addini() when the type is a union (tuple of tags) or a Literal of strings, but no explicit default was provided. Union and Literal types have no sensible implicit default (unlike 'string' which defaults to '' or 'bool' which defaults to False), so pytest requires an explicit default= argument.","triggerScenarios":"Calling parser.addini('mode', type=Literal['a','b']) or parser.addini('val', type=int | str) without a default= parameter. The check `default is NOTSET and isinstance(ini_type, (tuple, _IniLiteral))` triggers.","commonSituations":"Adding a new ini option with a Literal or union type and forgetting the default. Refactoring an existing string option to a Literal without adding default=.","solutions":["Pass an explicit default: parser.addini('mode', type=Literal['a','b'], default='a')","For union types, pick a default matching one member: parser.addini('val', type=int | str, default=0)","If no default makes sense, reconsider whether a union/Literal type is appropriate"],"exampleFix":"# before\nparser.addini('mode', type=Literal['fast', 'slow'])\n\n# after\nparser.addini('mode', type=Literal['fast', 'slow'], default='fast')","handlingStrategy":"validation","validationCode":"from typing import get_args, get_origin, Literal, Union, types\ndef needs_explicit_default(type_: object) -> bool:\n    if type_ is None:\n        return False\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# Usage: if needs_explicit_default(my_type): pass default= to addini","typeGuard":"from typing import get_args, get_origin, Literal, Union, types\ndef is_union_or_literal(type_: object) -> bool:\n    return get_origin(type_) in (Union, types.UnionType, Literal)","tryCatchPattern":null,"preventionTips":["Always pass default= when using a union or Literal type in addini","Pick a default value matching one of the union members or Literal choices","Remember that only scalar types (str, bool, int, float) get implicit defaults"],"tags":["pytest","config","addini","default","union","literal","plugin-api"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}