HKUDS/nanobot · error · TypeError

.PLUGIN module does not exist inside its package

Error message

{module_name}.PLUGIN {label} module does not exist inside its package: {target_module}

What it means

Existence validation in load_channel_package: the target module path stays inside the channel package, but neither the corresponding .py file nor a package __init__.py exists on disk, so the runtime/connector could never be imported. Typically a typo in the module name or a missing file in the shipped package.

Solutions

  1. Create the missing module file under nanobot/channels/<name>/ or fix the module name in the manifest target
  2. Ensure the file is included when the package/wheel is built (check packaging excludes)
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at nanobot/channels/plugin.py:169 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of HKUDS/nanobot@42f37dc4c0 (2026-08-26). Data as JSON: /api/errors/3b2126d338e47be8. Report an issue: GitHub.

Appendix: source

Thrown at nanobot/channels/plugin.py:169

    package_root = files("nanobot.channels").joinpath(name)
    targets = [("runtime", plugin.runtime)]
    if plugin.connector is not None:
        targets.append(("connector", plugin.connector))
    for label, target in targets:
        target_module, _ = _target_parts(target, label=label)
        if not target_module.startswith(f"{package_name}."):
            raise TypeError(
                f"{module_name}.PLUGIN {label} must stay inside {package_name}: "
                f"{target_module}"
            )
        target_parts = target_module.removeprefix(f"{package_name}.").split(".")
        target_file = package_root.joinpath(
            *target_parts[:-1],
            f"{target_parts[-1]}.py",
        )
        target_package = package_root.joinpath(*target_parts, "__init__.py")
        if not (target_file.is_file() or target_package.is_file()):
            raise TypeError(
                f"{module_name}.PLUGIN {label} module does not exist inside its package: "
                f"{target_module}"
            )
    if plugin.webui is not None:
        webui_entry = files("nanobot.channels").joinpath(name, *plugin.webui.split("/"))
        if not webui_entry.is_file():
            raise TypeError(
                f"{module_name}.PLUGIN webui entry does not exist: {plugin.webui}"
            )
    return plugin


__all__ = [
    "ChannelPlugin",
    "has_channel_package",
    "load_channel_package",
]

View on GitHub (pinned to 42f37dc4c0)