{"id":"8587a2c455b25ae2","repo":"pytest-dev/pytest","slug":"self-inipath-config-option-name-expects-a-s","errorCode":null,"errorMessage":"{self.inipath}: config option '{name}' expects a string, got {builtins.type(value).__name__}: {value!r}","messagePattern":"(.+?): config option '(.+?)' expects a string, got (.+?): (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/config/__init__.py","lineNumber":1864,"sourceCode":"            )\n        except (TypeError, ValueError) as e:\n            raise UsageError(str(e)) from e\n\n    def _getini_value(\n        self,\n        mode: Literal[\"ini\", \"toml\"],\n        name: str,\n        canonical_name: str,\n        type: str | _IniLiteral,\n        value: object,\n        default: Any,\n    ):\n        \"\"\"Convert a config value, read in the given mode, to the option's type.\"\"\"\n        if isinstance(type, _IniLiteral):\n            # A Literal value is a plain string checked against the registered\n            # choices, without coercion, in both ini and toml modes.\n            if not isinstance(value, str):\n                raise TypeError(\n                    f\"{self.inipath}: config option '{name}' expects a string, \"\n                    f\"got {builtins.type(value).__name__}: {value!r}\"\n                )\n            if value not in type.choices:\n                raise ValueError(\n                    f\"{self.inipath}: config option '{name}' expects one of \"\n                    f\"{_ini_type_repr(type)}, got {value!r}\"\n                )\n            return value\n        if mode == \"ini\":\n            # In ini mode, values are always str | list[str].\n            assert isinstance(value, (str, list))\n            return self._getini_ini(name, canonical_name, type, value, default)\n        elif mode == \"toml\":\n            return self._getini_toml(name, canonical_name, type, value, default)\n        else:\n            assert_never(mode)\n","sourceCodeStart":1846,"sourceCodeEnd":1882,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/config/__init__.py#L1846-L1882","documentation":"Raised by Config._getini_value (config/__init__.py:1860-1867) when an ini option is registered with a Literal/choice type (an _IniLiteral carrying .choices) but the value read from config is not a Python str. Literal choices are checked verbatim with no coercion, in both ini and toml modes, so a non-string (e.g. a TOML int) is rejected before the choice membership test.","triggerScenarios":"Registering addini(..., type=..., choices=[...]) and supplying, via TOML, a value of native non-string type (int/bool/list) for that key. getini() or any ini read then trips this branch.","commonSituations":"pyproject.toml sets a choice option to a bare integer or boolean instead of a quoted string; converting an .ini file to .toml and dropping the quotes; a plugin registering choices but the user supplying the wrong native TOML type.","solutions":["Quote the value in TOML so it parses as a string: my_opt = \"strict\".","Verify the value is one of the documented choices for that option.","If the option legitimately accepts non-string types, the plugin should register a non-Literal type (e.g. 'int')."],"exampleFix":"# before (pyproject.toml)\n[tool.pytest.ini_options]\nlog_level = 20   # Literal choice expects a string\n\n# after\nlog_level = \"INFO\"","handlingStrategy":"validation","validationCode":"def ensure_str_choice(value):\n    if not isinstance(value, str):\n        raise TypeError(f'choice option must be a string, got {type(value).__name__}')\n    return value","typeGuard":"def is_str_value(value) -> bool:\n    return isinstance(value, str)","tryCatchPattern":"try:\n    config.getini(name)\nexcept Exception:\n    # quote the value in pyproject.toml and rerun","preventionTips":["In TOML, always quote choice option values.","Validate config values programmatically before invoking pytest in CI.","Document the expected native type for each option."],"tags":["config","ini","toml","literal-choice","type-mismatch","pytest"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}