OpenBMB/ChatDev · error · ConfigError

file_types entries must be strings

Error message

file_types entries must be strings

What it means

FileSourceConfig.from_dict validates each entry of the optional 'file_types' list: every item must be a str. A non-string entry (int, dict, null) fails with the entry's index in the path.

Source

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

@dataclass
class FileSourceConfig(BaseConfig):
    source_path: str
    file_types: List[str] | None = None
    recursive: bool = True
    encoding: str = "utf-8"

    @classmethod
    def from_dict(cls, data: Mapping[str, Any], *, path: str) -> "FileSourceConfig":
        mapping = require_mapping(data, path)
        file_path = require_str(mapping, "path", path)
        file_types_value = mapping.get("file_types")
        file_types: List[str] | None = None
        if file_types_value is not None:
            items = ensure_list(file_types_value)
            normalized: List[str] = []
            for idx, item in enumerate(items):
                if not isinstance(item, str):
                    raise ConfigError("file_types entries must be strings", extend_path(path, f"file_types[{idx}]") )
                normalized.append(item)
            file_types = normalized

        recursive_value = mapping.get("recursive", True)
        if not isinstance(recursive_value, bool):
            raise ConfigError("recursive must be boolean", extend_path(path, "recursive"))

        encoding = optional_str(mapping, "encoding", path) or "utf-8"
        return cls(source_path=file_path, file_types=file_types, recursive=recursive_value, encoding=encoding, path=path)

    FIELD_SPECS = {
        "path": ConfigFieldSpec(
            name="path",
            display_name="File/Directory Path",
            type_hint="str",
            required=True,
            description="Path to file/directory to be indexed",
        ),

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Quote every entry in YAML: file_types: ['.py', '.md']
  2. Filter/str-coerce entries before building the dict: [str(t) for t in types if t]
  3. Remove null entries from the list

Example fix

# before
file_types: [.py, 3]
# after
file_types: ['.py', '.3']
Defensive patterns

Strategy: validation

Validate before calling

fts = cfg.get('file_types')
if fts is not None:
    cfg['file_types'] = [str(t) for t in fts if t is not None]

Type guard

def file_types_ok(cfg: dict) -> bool:
    fts = cfg.get('file_types')
    return fts is None or all(isinstance(t, str) for t in fts)

Try / catch

try:
    FileSourceConfig.from_dict(data, path='fs')
except ConfigError as e:
    if 'file_types[' in e.path:
        data['file_types'] = [str(t) for t in data['file_types'] if t is not None]
        FileSourceConfig.from_dict(data, path='fs')
    else:
        raise

Prevention

When it happens

Trigger: Passing file_types like ['py', 42] or [null, 'md']; YAML unquoted values that parse as booleans/numbers (e.g. on/off, 3).

Common situations: YAML gotchas: unquoted no/yes becoming booleans, numeric-looking extensions becoming ints; programmatic list building that includes None.

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/20c921a75768052e. Report an issue: GitHub.