{"record":{"id":"72da69a3fbfe9066","repo":"xai-org/x-algorithm","slug":"config-module-mod-name-r-has-no-key-ver-r-clo","errorCode":null,"errorMessage":"Config module {mod_name!r} has no key {ver!r}. Closest matches: {closest_matches}","messagePattern":"Config module (.+?) has no key (.+?)\\. Closest matches: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"phoenix/xrex/configs/config_loader.py","lineNumber":111,"sourceCode":"            raise ValueError(f\"No absolute config module found {mod_name!r}\")\n\n        try:\n            mod = importlib.import_module(f\"xrex.configs.{mod_name}\")\n        except ModuleNotFoundError:\n            raise ValueError(\n                f\"No config module {mod_name!r} found, either at the top level or under 'xrex.configs'\"\n            )\n\n    if not hasattr(mod, \"CONFIGS\"):\n        raise ValueError(\"Your config needs a global variable named CONFIGS\")\n\n    configs = mod.CONFIGS\n    if ver not in configs:\n        logger.warning(\n            f\"Couldn't find a valid config ({len(configs)=}), searching for closest matches...\"\n        )\n        closest_matches = difflib.get_close_matches(ver, configs, n=5, cutoff=0)\n        raise ValueError(\n            f\"Config module {mod_name!r} has no key {ver!r}. Closest matches: {closest_matches}\"\n        )\n    return _apply_deployment_defaults(configs[ver])\n","sourceCodeStart":93,"sourceCodeEnd":115,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/phoenix/xrex/configs/config_loader.py#L93-L115","documentation":"The named config module was found and has a CONFIGS dict, but the requested version key is not present. The loader computes difflib close matches and includes them in the error to help diagnose typos or stale version names.","triggerScenarios":"Calling get_named_config(mod_name, ver) with a ver that is not a key in mod.CONFIGS — e.g. \"2024-01-15\" when keys are dates like \"20240115\", or a misspelled/deprecated config name.","commonSituations":"Typos or formatting differences in the version string; using a version removed after a config cleanup; a new version not yet merged on the current branch; date-formatted keys with inconsistent separators.","solutions":["Read the closest_matches list in the error message and use the exact key shown","Print the available keys: import my_cfg; print(my_cfg.CONFIGS.keys())","Normalize your version string to the module's key format (e.g. strip dashes, zero-pad)","If the key should exist, add it to CONFIGS or pull the branch that contains it"],"exampleFix":"# before\ncfg = get_named_config(\"recs_v2\", \"2024-1-5\")\n\n# after\ncfg = get_named_config(\"recs_v2\", \"20240105\")  # exact CONFIGS key","handlingStrategy":"validation","validationCode":"import importlib\n\ndef check_version(mod_name: str, ver: str) -> None:\n    mod = importlib.import_module(mod_name)\n    keys = set(mod.CONFIGS)\n    if ver not in keys:\n        import difflib\n        matches = difflib.get_close_matches(ver, mod.CONFIGS, n=5, cutoff=0)\n        raise KeyError(f\"{ver!r} not in {mod_name}; did you mean {matches}?\")","typeGuard":"def is_known_version(mod, ver: str) -> bool:\n    return ver in getattr(mod, \"CONFIGS\", {})","tryCatchPattern":"try:\n    cfg = get_named_config(mod_name, ver)\nexcept ValueError as e:\n    if \"Closest matches\" in str(e):\n        # parse suggestions and retry with the exact key\n        raise\n    raise","preventionTips":["Pin config version strings from a single constants module instead of hand-typing them","Fail fast at startup by listing CONFIGS keys before launching long jobs","Keep version key formatting consistent (one date/style convention) across modules"],"tags":["config","lookup","typo","python"],"backgroundTag":"invalid-config-value","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}