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 LocalCommandLineCodeExecutor: functions_module (the module name under which generated function files are saved and imported) must be a valid Python identifier - it becomes the filename of the generated .py module that gets executed during setup.
Source
Thrown at python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py:198
"Using the current directory as work_dir is deprecated.",
DeprecationWarning,
stacklevel=2,
)
if isinstance(work_dir, str):
self._work_dir = Path(work_dir)
else:
self._work_dir = work_dir
self._work_dir.mkdir(exist_ok=True)
self._functions = functions
# 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
if not functions_module.isidentifier():
raise ValueError("Module name must be a valid Python identifier")
self._functions_module = functions_module
self._cleanup_temp_files = cleanup_temp_files
self._virtual_env_context: Optional[SimpleNamespace] = virtual_env_context
self._temp_dir: Optional[tempfile.TemporaryDirectory[str]] = None
self._started = False
# Check the current event loop policy if on windows.
if sys.platform == "win32":
current_policy = asyncio.get_event_loop_policy()
if hasattr(asyncio, "WindowsProactorEventLoopPolicy") and not isinstance(
current_policy, asyncio.WindowsProactorEventLoopPolicy
):
warnings.warn(
"The current event loop policy is not WindowsProactorEventLoopPolicy. "
"This may cause issues with subprocesses. "
"Try setting the event loop policy to WindowsProactorEventLoopPolicy. "View on GitHub (pinned to 027ecf0a37)
Solutions
- Use a plain identifier like 'functions' (the default) or 'my_functions'.
- Strip '.py' and replace invalid characters before passing, e.g. re.sub(r'\W|^(?=\d)', '_', name).
- Avoid Python keywords ('import', 'class', ...); pick a descriptive non-keyword name.
Example fix
# before executor = LocalCommandLineCodeExecutor(functions_module="my-functions.py") # after import re name = re.sub(r"\W", "_", "my-functions.py") executor = LocalCommandLineCodeExecutor(functions_module=name)
Defensive patterns
Strategy: validation
Validate before calling
import re
def to_identifier(name: str) -> str:
ident = re.sub(r"\W", "_", name.strip())
if not ident or ident[0].isdigit():
ident = f"_{ident}"
assert ident.isidentifier()
return ident Type guard
import keyword
def is_valid_module_name(name: object) -> bool:
return isinstance(name, str) and name.isidentifier() and not keyword.iskeyword(name) Try / catch
try:
LocalCommandLineCodeExecutor(functions_module=name)
except ValueError as e:
if "valid Python identifier" in str(e):
import re
executor = LocalCommandLineCodeExecutor(functions_module=re.sub(r"\W", "_", name))
else:
raise Prevention
- Use the default 'functions' module name unless you need multiple executors.
- Sanitize user-derived names with str.isidentifier() checks before passing.
When it happens
Trigger: Passing functions_module values like 'my-functions', 'functions.py', 'my functions', or an empty string - anything failing str.isidentifier(). Names starting with a digit also fail; keywords like 'import' pass this check but break at import time.
Common situations: Deriving the module name from file paths or user input, including the '.py' extension by mistake, hyphenated project names, sanitizing config strings down to an empty string.
Related errors
- The agent name must be a valid Python identifier.
- Module name must be a valid Python identifier
- Timeout must be greater than or equal to 1.
- Unsupported config type {config.GetType()}
- Messages should not be provided in options
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/11b2b5e8e4b014bd.
Report an issue: GitHub.