xai-org/x-algorithm · error · ValueError

Your config needs a global variable named CONFIGS

Error message

Your config needs a global variable named CONFIGS

What it means

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.

Source

Thrown at phoenix/xrex/configs/config_loader.py:103

            )
        mod_name, ver = parts

    try:
        mod = importlib.import_module(mod_name)
    except ModuleNotFoundError:
        depth = mod_name.count(".")
        if depth > 1:
            raise ValueError(f"No absolute config module found {mod_name!r}")

        try:
            mod = importlib.import_module(f"xrex.configs.{mod_name}")
        except ModuleNotFoundError:
            raise ValueError(
                f"No config module {mod_name!r} found, either at the top level or under 'xrex.configs'"
            )

    if not hasattr(mod, "CONFIGS"):
        raise ValueError("Your config needs a global variable named CONFIGS")

    configs = mod.CONFIGS
    if ver not in configs:
        logger.warning(
            f"Couldn't find a valid config ({len(configs)=}), searching for closest matches..."
        )
        closest_matches = difflib.get_close_matches(ver, configs, n=5, cutoff=0)
        raise ValueError(
            f"Config module {mod_name!r} has no key {ver!r}. Closest matches: {closest_matches}"
        )
    return _apply_deployment_defaults(configs[ver])

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Add a module-level dict named CONFIGS to the module: CONFIGS = {'v1': {...}, 'v2': {...}}
  2. Check for typos/case: it must be exactly CONFIGS at module top level, not nested in a class or function
  3. If configs live elsewhere, move or re-export them: from .impl import CONFIGS
  4. Verify you pointed at the right module — confirm the imported module is the one you edited (top-level vs xrex.configs shadowing)

Example fix

# before
# my_cfg.py
MY_CONFIGS = {"v1": {...}}

# after
# my_cfg.py
CONFIGS = {"v1": {...}}
Defensive patterns

Strategy: validation

Validate before calling

import importlib

def has_configs(mod_name: str) -> bool:
    try:
        mod = importlib.import_module(mod_name)
    except ModuleNotFoundError:
        return False
    return hasattr(mod, "CONFIGS")

Type guard

def is_valid_config_module(mod) -> bool:
    return hasattr(mod, "CONFIGS") and isinstance(mod.CONFIGS, dict)

Try / catch

try:
    cfg = get_named_config(mod_name, ver)
except ValueError as e:
    if "CONFIGS" in str(e):
        raise SystemExit(f"Fix {mod_name}: add CONFIGS dict") from e
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/533b03093eae8c3a. Report an issue: GitHub.