{"record":{"id":"533b03093eae8c3a","repo":"xai-org/x-algorithm","slug":"your-config-needs-a-global-variable-named-configs","errorCode":null,"errorMessage":"Your config needs a global variable named CONFIGS","messagePattern":"Your config needs a global variable named CONFIGS","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"phoenix/xrex/configs/config_loader.py","lineNumber":103,"sourceCode":"            )\n        mod_name, ver = parts\n\n    try:\n        mod = importlib.import_module(mod_name)\n    except ModuleNotFoundError:\n        depth = mod_name.count(\".\")\n        if depth > 1:\n            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":85,"sourceCodeEnd":115,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/phoenix/xrex/configs/config_loader.py#L85-L115","documentation":"The config loader dynamically imports a module (by name, at top level or under 'xrex.configs') and requires it to expose a module-level dict named CONFIGS. If the module imports successfully but has no CONFIGS global, this ValueError is raised because the loader has no registry of named configs to look in.","triggerScenarios":"Calling get_named_config(mod_name, ver) where mod_name resolves to a module that lacks a top-level CONFIGS variable — e.g. the module defines configs under a different name (CONFIG, CONFIG_REGISTRY), only has helper functions, or CONFIGS is nested inside a class/function.","commonSituations":"Renaming the dict during refactoring; creating a new config module from a template and forgetting the CONFIGS = {...} block; typo in the variable name; expecting the loader to auto-discover configs when they are defined lazily inside a function.","solutions":["Add a module-level dict named CONFIGS to the module: CONFIGS = {'v1': {...}, 'v2': {...}}","Check for typos/case: it must be exactly CONFIGS at module top level, not nested in a class or function","If configs live elsewhere, move or re-export them: from .impl import CONFIGS","Verify you pointed at the right module — confirm the imported module is the one you edited (top-level vs xrex.configs shadowing)"],"exampleFix":"# before\n# my_cfg.py\nMY_CONFIGS = {\"v1\": {...}}\n\n# after\n# my_cfg.py\nCONFIGS = {\"v1\": {...}}","handlingStrategy":"validation","validationCode":"import importlib\n\ndef has_configs(mod_name: str) -> bool:\n    try:\n        mod = importlib.import_module(mod_name)\n    except ModuleNotFoundError:\n        return False\n    return hasattr(mod, \"CONFIGS\")","typeGuard":"def is_valid_config_module(mod) -> bool:\n    return hasattr(mod, \"CONFIGS\") and isinstance(mod.CONFIGS, dict)","tryCatchPattern":"try:\n    cfg = get_named_config(mod_name, ver)\nexcept ValueError as e:\n    if \"CONFIGS\" in str(e):\n        raise SystemExit(f\"Fix {mod_name}: add CONFIGS dict\") from e\n    raise","preventionTips":["Use a shared config-module template that always defines CONFIGS = {}","Add a unit test asserting every config module under xrex/configs exposes CONFIGS","Lint for module-level CONFIGS via a repo conftest import check"],"tags":["config","module-loading","valueerror","python"],"backgroundTag":"invalid-config-value","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}