OpenBMB/ChatDev · error · ConfigError

file_sources must contain at least one entry

Error message

file_sources must contain at least one entry

What it means

FileMemoryConfig.from_dict requires a non-empty 'file_sources' list (missing key yields None, which ensure_list turns into an empty list and also fails). A file memory with no sources has nothing to index, so it is rejected.

Source

Thrown at entity/configs/node/memory.py:203

            required=False,
            description="Optional embedding configuration",
            child=EmbeddingConfig,
        ),
    }


@dataclass
class FileMemoryConfig(BaseConfig):
    index_path: str | None = None
    file_sources: List[FileSourceConfig] = field(default_factory=list)
    embedding: EmbeddingConfig | None = None

    @classmethod
    def from_dict(cls, data: Mapping[str, Any], *, path: str) -> "FileMemoryConfig":
        mapping = require_mapping(data, path)
        sources_raw = ensure_list(mapping.get("file_sources"))
        if not sources_raw:
            raise ConfigError("file_sources must contain at least one entry", extend_path(path, "file_sources"))
        sources: List[FileSourceConfig] = []
        for idx, item in enumerate(sources_raw):
            sources.append(FileSourceConfig.from_dict(item, path=extend_path(path, f"file_sources[{idx}]")))

        index_path = optional_str(mapping, "index_path", path)
        if index_path is None:
            index_path = optional_str(mapping, "memory_path", path)

        embedding_cfg = None
        if "embedding" in mapping and mapping["embedding"] is not None:
            embedding_cfg = EmbeddingConfig.from_dict(mapping["embedding"], path=extend_path(path, "embedding"))

        return cls(index_path=index_path, file_sources=sources, embedding=embedding_cfg, path=path)

    FIELD_SPECS = {
        "index_path": ConfigFieldSpec(
            name="index_path",
            display_name="Index Path",

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Add at least one file source entry: "file_sources": [{"path": "./docs"}]
  2. If no file memory is wanted, remove the file memory node/config entirely rather than emptying the list
  3. When generating dynamically, skip creating FileMemoryConfig when the sources list is empty

Example fix

# before
{"file_sources": []}
# after
{"file_sources": [{"path": "./docs", "recursive": true}]}
Defensive patterns

Strategy: validation

Validate before calling

sources = cfg.get('file_sources') or []
if not sources:
    raise ValueError('file memory requires >=1 source')  # or skip creating the node

Type guard

def has_file_sources(cfg: dict) -> bool:
    s = cfg.get('file_sources')
    return isinstance(s, list) and len(s) > 0

Try / catch

try:
    FileMemoryConfig.from_dict(data, path='fm')
except ConfigError as e:
    if 'file_sources' in e.path:
        data['file_sources'] = [{'path': DEFAULT_DOCS_DIR}]
        FileMemoryConfig.from_dict(data, path='fm')
    else:
        raise

Prevention

When it happens

Trigger: Omitting 'file_sources', passing an empty list [], or passing file_sources: null. Each FileSourceConfig in the list is then validated individually.

Common situations: Dynamic config generation where the sources list ends up empty; commenting out all sources for testing; forgetting the key when authoring a memory node.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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