{"record":{"id":"20c921a75768052e","repo":"OpenBMB/ChatDev","slug":"file-types-entries-must-be-strings","errorCode":null,"errorMessage":"file_types entries must be strings","messagePattern":"file_types entries must be strings","errorType":"validation","errorClass":"ConfigError","httpStatus":null,"severity":"error","filePath":"entity/configs/node/memory.py","lineNumber":111,"sourceCode":"@dataclass\nclass FileSourceConfig(BaseConfig):\n    source_path: str\n    file_types: List[str] | None = None\n    recursive: bool = True\n    encoding: str = \"utf-8\"\n\n    @classmethod\n    def from_dict(cls, data: Mapping[str, Any], *, path: str) -> \"FileSourceConfig\":\n        mapping = require_mapping(data, path)\n        file_path = require_str(mapping, \"path\", path)\n        file_types_value = mapping.get(\"file_types\")\n        file_types: List[str] | None = None\n        if file_types_value is not None:\n            items = ensure_list(file_types_value)\n            normalized: List[str] = []\n            for idx, item in enumerate(items):\n                if not isinstance(item, str):\n                    raise ConfigError(\"file_types entries must be strings\", extend_path(path, f\"file_types[{idx}]\") )\n                normalized.append(item)\n            file_types = normalized\n\n        recursive_value = mapping.get(\"recursive\", True)\n        if not isinstance(recursive_value, bool):\n            raise ConfigError(\"recursive must be boolean\", extend_path(path, \"recursive\"))\n\n        encoding = optional_str(mapping, \"encoding\", path) or \"utf-8\"\n        return cls(source_path=file_path, file_types=file_types, recursive=recursive_value, encoding=encoding, path=path)\n\n    FIELD_SPECS = {\n        \"path\": ConfigFieldSpec(\n            name=\"path\",\n            display_name=\"File/Directory Path\",\n            type_hint=\"str\",\n            required=True,\n            description=\"Path to file/directory to be indexed\",\n        ),","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/OpenBMB/ChatDev/blob/4fb2db0ea90375ce1059f44fe03ffbd191a7a169/entity/configs/node/memory.py#L93-L129","documentation":"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.","triggerScenarios":"Passing file_types like ['py', 42] or [null, 'md']; YAML unquoted values that parse as booleans/numbers (e.g. on/off, 3).","commonSituations":"YAML gotchas: unquoted no/yes becoming booleans, numeric-looking extensions becoming ints; programmatic list building that includes None.","solutions":["Quote every entry in YAML: file_types: ['.py', '.md']","Filter/str-coerce entries before building the dict: [str(t) for t in types if t]","Remove null entries from the list"],"exampleFix":"# before\nfile_types: [.py, 3]\n# after\nfile_types: ['.py', '.3']","handlingStrategy":"validation","validationCode":"fts = cfg.get('file_types')\nif fts is not None:\n    cfg['file_types'] = [str(t) for t in fts if t is not None]","typeGuard":"def file_types_ok(cfg: dict) -> bool:\n    fts = cfg.get('file_types')\n    return fts is None or all(isinstance(t, str) for t in fts)","tryCatchPattern":"try:\n    FileSourceConfig.from_dict(data, path='fs')\nexcept ConfigError as e:\n    if 'file_types[' in e.path:\n        data['file_types'] = [str(t) for t in data['file_types'] if t is not None]\n        FileSourceConfig.from_dict(data, path='fs')\n    else:\n        raise","preventionTips":["Quote YAML extension entries","Filter None out of generated lists","Watch YAML implicit typing (yes/no, numbers)"],"tags":["config","memory","file","validation","python","yaml"],"backgroundTag":"schema-validation-failed","analyzedSha":"4fb2db0ea90375ce1059f44fe03ffbd191a7a169","analyzedAt":"2026-08-27T14:35:29.622Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}