cocoindex-io/cocoindex · error · RuntimeError

Failed to load module

Error message

Failed to load module '{module_ref}'

What it means

The `cocoindex ls` CLI loads the user's app module to discover registered apps; if the module fails to import/register (UserAppLoaderError), the loader wraps it in this RuntimeError naming the module. The original loader error is chained as __cause__.

Solutions

  1. Run the CLI from the directory containing the module, or pass the correct dotted module path (e.g. myapp.main)
  2. Import the module directly with python -c "import mymodule" to see the underlying error
  3. Install missing dependencies the module imports
  4. Ensure the module actually defines and registers cocoindex apps at import time

Example fix

# before
cocoindex ls my_app  # Failed to load module
// after
cd /path/to/project
cocoindex ls my_app.main  # or fix import error first
Defensive patterns

Strategy: try-catch

Validate before calling

import importlib
try:
    importlib.import_module("my_app")
except ImportError as e:
    raise SystemExit(f"module not importable: {e}")

Try / catch

try:
    result = subprocess.run(["cocoindex", "ls", module], capture_output=True)
except RuntimeError as e:
    print(f"{e}; cause: {e.__cause__}")

Prevention

When it happens

Trigger: Running `cocoindex ls mymodule` where mymodule cannot be imported — wrong module path, ImportError inside the module, module doesn't call Environment/App registration code, or missing dependencies imported by the module.

Common situations: Typo in module reference (dots vs file path); running from the wrong working directory so the module isn't importable; the app file raising on import due to missing env vars or packages.

Related errors


AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/e77fd0ef76257f6c. Report an issue: GitHub.

Appendix: source

Thrown at python/cocoindex/cli.py:232

) -> bool:
    """Print a group of apps under an environment. Returns True if any app is not persisted."""
    has_missing = False
    click.echo(_format_env_header(env_name, db_path))
    for app in sorted(apps, key=lambda a: a._name):
        if app._name in persisted_names:
            click.echo(f"  {app._name}")
        else:
            click.echo(f"  {app._name} [+]")
            has_missing = True
    return has_missing


async def _ls_from_module_async(module_ref: str) -> None:
    """List apps from a loaded module, grouped by environment. Uses async env access so CLI never starts the background loop."""
    try:
        load_user_app(module_ref)
    except UserAppLoaderError as e:
        raise RuntimeError(f"Failed to load module '{module_ref}'") from e

    try:
        env_infos = get_registered_environment_infos()
        if not env_infos:
            click.echo(f"No apps are defined in '{module_ref}'.")
            return

        # Sort: explicit environments first (by name), default environment last
        def sort_key(info: EnvironmentInfo) -> tuple[int, str]:
            env = info.env
            if env is default_env_lazy():
                return (1, "")
            return (0, info.env_name or "")

        sorted_infos = sorted(env_infos, key=sort_key)

        has_missing = False
        first_group = True

View on GitHub (pinned to e84aa99b32)