OpenBMB/ChatDev · error · ValueError

Functions directory does not exist

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.

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.

Appendix: 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)