{"record":{"id":"b02163d1282b3301","repo":"pypa/pip","slug":"key-does-not-contain-dot-separated-section-and-key","errorCode":null,"errorMessage":"Key does not contain dot separated section and key. Perhaps you wanted to use 'global.{name}' instead?","messagePattern":"Key does not contain dot separated section and key\\. Perhaps you wanted to use 'global\\.(.+?)' instead\\?","errorType":"exception","errorClass":"ConfigurationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/configuration.py","lineNumber":65,"sourceCode":"\nlogger = getLogger(__name__)\n\n\n# NOTE: Maybe use the optionx attribute to normalize keynames.\ndef _normalize_name(name: str) -> str:\n    \"\"\"Make a name consistent regardless of source (environment or file)\"\"\"\n    name = name.lower().replace(\"_\", \"-\")\n    name = name.removeprefix(\"--\")  # only prefer long opts\n    return name\n\n\ndef _disassemble_key(name: str) -> list[str]:\n    if \".\" not in name:\n        error_message = (\n            \"Key does not contain dot separated section and key. \"\n            f\"Perhaps you wanted to use 'global.{name}' instead?\"\n        )\n        raise ConfigurationError(error_message)\n    return name.split(\".\", 1)\n\n\ndef get_configuration_files() -> dict[Kind, list[str]]:\n    global_config_files = [\n        os.path.join(path, CONFIG_BASENAME) for path in appdirs.site_config_dirs(\"pip\")\n    ]\n\n    site_config_file = os.path.join(sys.prefix, CONFIG_BASENAME)\n    legacy_config_file = os.path.join(\n        os.path.expanduser(\"~\"),\n        \"pip\" if WINDOWS else \".pip\",\n        CONFIG_BASENAME,\n    )\n    new_config_file = os.path.join(appdirs.user_config_dir(\"pip\"), CONFIG_BASENAME)\n    return {\n        kinds.GLOBAL: global_config_files,\n        kinds.SITE: [site_config_file],","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/configuration.py#L47-L83","documentation":"Raised by _disassemble_key() when a configuration key passed to pip config does not contain a dot separator. pip's configuration API requires keys in 'section.name' form (e.g. 'global.index-url'), because it maps to an INI section plus option. A bare key like 'index-url' is ambiguous and pip suggests prefixing it with a section such as 'global.'.","triggerScenarios":"Running `pip config set index-url https://...` (missing section prefix), or `pip config get timeout`, or `pip config unset index-url`. Any config subcommand that ultimately calls set_value/get_value/unset_value and hits _disassemble_key with a dotless string.","commonSituations":"Forgetting the section prefix when scripting `pip config set`; copying a pip.conf option name without its section; muscle memory from tools that take bare option names.","solutions":["Prefix the key with the appropriate section: `global.`, `user.`, or `site.` — e.g. `pip config set global.index-url https://...`.","Consult `pip config list` to see the correct section.key format for existing entries.","If editing a specific file, use `pip config set --site global.index-url ...` (the section prefix is always required regardless of --user/--global/--site scope)."],"exampleFix":"# before\npip config set index-url https://pypi.org/simple\n# after\npip config set global.index-url https://pypi.org/simple","handlingStrategy":"validation","validationCode":"import re\n\ndef validate_config_key(key: str) -> str:\n    if not re.match(r'^(global|user|site|install)\\.[A-Za-z0-9_-]+$', key):\n        raise ValueError(f\"Config key must be 'section.name', got: {key!r}\")\n    return key\n","typeGuard":"def is_dotted_config_key(key: str) -> bool:\n    return '.' in key and key.split('.', 1)[0] in {'global', 'user', 'site', 'install'}\n","tryCatchPattern":null,"preventionTips":["Always prefix config keys with a section (global./user./site.).","Use `pip config list` to learn the correct key format."],"tags":["pip","config","configuration","cli","key-format"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}