microsoft/autogen · error · ValueError

Module name must be a valid Python identifier

Error message

Module name must be a valid Python identifier

What it means

Constructor validation in DockerCommandLineCodeExecutor: the `functions_module` argument (the module name the executor writes your `functions` to inside the container) must be a valid Python identifier, because generated code imports it via `import <functions_module>`. Names with dashes, dots, leading digits, or spaces are rejected.

Source

Thrown at python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py:227

        # Handle bind_dir
        self._bind_dir: Optional[Path] = None
        if bind_dir is not None:
            self._bind_dir = Path(bind_dir) if isinstance(bind_dir, str) else bind_dir
        else:
            self._bind_dir = self._work_dir  # Default to work_dir if not provided

        # Track temporary directory
        self._temp_dir: Optional[tempfile.TemporaryDirectory[str]] = None
        self._temp_dir_path: Optional[Path] = None

        self._started = False

        self._auto_remove = auto_remove
        self._stop_container = stop_container
        self._image = image

        if not functions_module.isidentifier():
            raise ValueError("Module name must be a valid Python identifier")

        self._functions_module = functions_module
        self._functions = functions
        self._extra_volumes = extra_volumes if extra_volumes is not None else {}
        self._extra_hosts = extra_hosts if extra_hosts is not None else {}
        self._init_command = init_command
        self._delete_tmp_files = delete_tmp_files
        self._device_requests = device_requests

        # Setup could take some time so we intentionally wait for the first code block to do it.
        if len(functions) > 0:
            self._setup_functions_complete = False
        else:
            self._setup_functions_complete = True

        self._container: Container | None = None
        self._running = False

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Use a plain identifier: functions_module="functions" (default) or "my_functions"
  2. If the name comes from external config, sanitize it: re.sub(r'\W|^(?=\d)', '_', name).strip('_')
  3. Prefer leaving the default unless multiple executors share a container

Example fix

# before
executor = DockerCommandLineCodeExecutor(functions_module="agent-funcs")

# after
executor = DockerCommandLineCodeExecutor(functions_module="agent_funcs")
Defensive patterns

Strategy: validation

Validate before calling

import re

def to_identifier(name: str) -> str:
    ident = re.sub(r"\W", "_", name)
    if not ident or ident[0].isdigit():
        ident = f"f_{ident}"
    assert ident.isidentifier()
    return ident

Type guard

def is_valid_module_name(name: str) -> bool:
    return isinstance(name, str) and name.isidentifier()

Try / catch

null

Prevention

When it happens

Trigger: Passing functions_module="my-functions", "funcs.v2", "2funcs", or an empty string. The generated functions file is written as <functions_module>.py and imported, so non-identifier names would break that import; the check fails fast at construction.

Common situations: Deriving the module name from a file stem or app name containing dashes/dots; i18n tooling or templating inserting spaces; passing a filename instead of a module name.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/ac74850e2c15749e. Report an issue: GitHub.