xai-org/x-algorithm · error · ValueError

Module '{base_module_name}' is not a package containing conf

Error message

Module '{base_module_name}' is not a package containing configs.

What it means

get_all_configs_from_module discovers configs by iterating a package's __path__. If the imported base module is a plain module (no __path__), it cannot contain child config modules, so this ValueError is raised.

Source

Thrown at phoenix/python/common/xai-configlib/src/xai_configlib/__init__.py:612

    if ver not in configs:
        avail = ", ".join(configs.keys())
        raise ValueError(f"Config module {mod_name!r} has no key {ver!r}. Available keys: {avail}")
    return configs[ver]


class DiscoveredConfigsInModule(NamedTuple):
    configs: dict[str, Config]
    failing_modules: list[str]


def get_all_configs_from_module(
    base_module_name: str,
    ignore_loading_errors: bool = False,
) -> DiscoveredConfigsInModule:
    mod = get_module(base_module_name)
    if not hasattr(mod, "__path__"):
        raise ValueError(f"Module '{base_module_name}' is not a package containing configs.")

    configs: dict[str, Config] = {}
    failing_modules: list[str] = []
    for _, name, _is_pkg in pkgutil.iter_modules(mod.__path__):
        try:
            child_mod = get_module(f"{base_module_name}.{name}")
        except Exception:
            failing_modules.append(f"{base_module_name}.{name}")
            logger.warning(
                f"Failed to load eval config module {base_module_name}.{name}",
                exc_info=True,
            )
            if ignore_loading_errors:
                continue
            raise
        child_mod_configs = get_configs_from_mod(child_mod)
        if child_mod_configs is None:
            continue

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Pass the package name (directory with __init__.py), not a leaf module
  2. Ensure the configs directory has an __init__.py
  3. Check sys.path/imports so the intended package, not a same-named module, is imported

Example fix

# before
get_all_configs_from_module("xrex.configs.my_cfg")
# after
get_all_configs_from_module("xrex.configs")
Defensive patterns

Strategy: validation

Validate before calling

import importlib
mod = importlib.import_module(base_module_name)
assert hasattr(mod, "__path__"), f"{base_module_name} is not a package"

Type guard

def is_package(mod) -> bool:
    return hasattr(mod, "__path__")

Prevention

When it happens

Trigger: Passing a module name that resolves to a single-file module (e.g. 'xrex.configs.base') instead of a package directory; or the package lost its __init__.py so it imports as a namespace-less module.

Common situations: Reorganizing configs from a package into a flat module, missing __init__.py after a refactor, or passing a dotted config name where a package name is expected.

Related errors


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