OpenBMB/ChatDev · error · ValueError

Functions directory does not exist: {self.functions_dir}

Error message

Functions directory does not exist: {self.functions_dir}

What it means

FunctionManager.load_functions raises ValueError when the configured functions directory does not exist on disk. Loading is lazy (first call to get_function/list_functions/call_function or refresh triggers it), so the error surfaces at first use, not at construction.

Source

Thrown at utils/function_manager.py:48

EDGE_FUNCTION_DIR = _resolve_dir(_DEFAULT_EDGE_FUNCTION_DIR, _EDGE_FUNCTION_ENV).resolve()
EDGE_PROCESSOR_FUNCTION_DIR = _resolve_dir(_DEFAULT_EDGE_PROCESSOR_DIR, _EDGE_PROCESSOR_FUNCTION_ENV).resolve()


class FunctionManager:
    """Unified function manager for loading and managing functions across the project."""

    def __init__(self, functions_dir: str | Path = "functions") -> None:
        self.functions_dir = Path(functions_dir)
        self.functions: Dict[str, Callable] = {}
        self._loaded = False

    def load_functions(self) -> None:
        """Load all Python functions from functions directory."""
        if self._loaded:
            return
            
        if not self.functions_dir.exists():
            raise ValueError(f"Functions directory does not exist: {self.functions_dir}")

        for file in self.functions_dir.rglob("*.py"):
            if file.name.startswith("_") or file.name == "__init__.py":
                continue
            if "__pycache__" in file.parts:
                continue
                
            module_name = self._build_module_name(file)
            try:
                # Import module dynamically
                spec = importlib.util.spec_from_file_location(module_name, file)
                if spec is None or spec.loader is None:
                    continue
                    
                module = importlib.util.module_from_spec(spec)
                spec.loader.exec_module(module)

                current_file = file.resolve()

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Create the directory (even empty) or fix the configured path
  2. Pass an absolute path derived from a known base (e.g. Path(__file__).parent / 'functions')
  3. If no custom functions are used, ensure the code skips FunctionManager or the dir is created at startup

Example fix

# before
fm = FunctionManager(functions_dir=Path("functions"))
# after
fdir = Path("functions").resolve()
fdir.mkdir(parents=True, exist_ok=True)
fm = FunctionManager(functions_dir=fdir)
Defensive patterns

Strategy: validation

Validate before calling

fdir = Path(functions_dir).resolve()
if not fdir.is_dir():
    fdir.mkdir(parents=True, exist_ok=True)  # or fail fast with clear message

Type guard

def has_functions_dir(d: str | Path) -> bool:
    return Path(d).is_dir()

Try / catch

try:
    fm.list_functions()
except ValueError as e:
    if 'does not exist' in str(e):
        fix_functions_path_or_create()

Prevention

When it happens

Trigger: Instantiating FunctionManager with a functions_dir path that is wrong or not yet created; relative path resolved from a different CWD; directory deleted or not shipped in a container/deployment.

Common situations: Default ./functions dir absent in a fresh clone or slim Docker image; path configured via env var pointing to a typo'd location; running the server from a different working directory.

Related errors


AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27). Data as JSON: /api/errors/40198d492de00d37. Report an issue: GitHub.