xai-org/x-algorithm · error · ValueError

Config module {mod_name!r} has no key {ver!r}. Closest match

Error message

Config module {mod_name!r} has no key {ver!r}. Closest matches: {closest_matches}

What it means

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.

Source

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

            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. Read the closest_matches list in the error message and use the exact key shown
  2. Print the available keys: import my_cfg; print(my_cfg.CONFIGS.keys())
  3. Normalize your version string to the module's key format (e.g. strip dashes, zero-pad)
  4. If the key should exist, add it to CONFIGS or pull the branch that contains it

Example fix

# before
cfg = get_named_config("recs_v2", "2024-1-5")

# after
cfg = get_named_config("recs_v2", "20240105")  # exact CONFIGS key
Defensive patterns

Strategy: validation

Validate before calling

import importlib

def check_version(mod_name: str, ver: str) -> None:
    mod = importlib.import_module(mod_name)
    keys = set(mod.CONFIGS)
    if ver not in keys:
        import difflib
        matches = difflib.get_close_matches(ver, mod.CONFIGS, n=5, cutoff=0)
        raise KeyError(f"{ver!r} not in {mod_name}; did you mean {matches}?")

Type guard

def is_known_version(mod, ver: str) -> bool:
    return ver in getattr(mod, "CONFIGS", {})

Try / catch

try:
    cfg = get_named_config(mod_name, ver)
except ValueError as e:
    if "Closest matches" in str(e):
        # parse suggestions and retry with the exact key
        raise
    raise

Prevention

When it happens

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

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

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/72da69a3fbfe9066. Report an issue: GitHub.