OpenBMB/ChatDev · error · ConfigError
memories must be a list
Error message
memories must be a list
What it means
The 'memories' key of an agent model config is present and non-null but is not a list. Memories are parsed as a list of MemoryAttachmentConfig entries; any other shape is rejected before item parsing begins.
Source
Thrown at entity/configs/node/agent.py:384
tooling_cfg: List[ToolingConfig] = []
if "tooling" in mapping and mapping["tooling"] is not None:
raw_tooling = mapping["tooling"]
if not isinstance(raw_tooling, list):
raise ConfigError("tooling must be a list", extend_path(path, "tooling"))
for idx, item in enumerate(raw_tooling):
tooling_cfg.append(
ToolingConfig.from_dict(item, path=extend_path(path, f"tooling[{idx}]"))
)
thinking_cfg = None
if "thinking" in mapping and mapping["thinking"] is not None:
thinking_cfg = ThinkingConfig.from_dict(mapping["thinking"], path=extend_path(path, "thinking"))
memories_cfg: List[MemoryAttachmentConfig] = []
if "memories" in mapping and mapping["memories"] is not None:
raw_memories = mapping["memories"]
if not isinstance(raw_memories, list):
raise ConfigError("memories must be a list", extend_path(path, "memories"))
for idx, item in enumerate(raw_memories):
memories_cfg.append(
MemoryAttachmentConfig.from_dict(item, path=extend_path(path, f"memories[{idx}]"))
)
retry_cfg = None
if "retry" in mapping and mapping["retry"] is not None:
retry_cfg = AgentRetryConfig.from_dict(mapping["retry"], path=extend_path(path, "retry"))
skills_cfg = None
if "skills" in mapping and mapping["skills"] is not None:
skills_cfg = AgentSkillsConfig.from_dict(mapping["skills"], path=extend_path(path, "skills"))
return cls(
provider=provider,
base_url=base_url,
name=model_name,
role=role,View on GitHub (pinned to 4fb2db0ea9)
Solutions
- Wrap the attachment in a list: "memories": [{...}]
- Check YAML list syntax (dash items) under 'memories'
- Omit 'memories' or set null if no memory attachments are wanted
Example fix
// before
"memories": {"memory_id": "m1"}
// after
"memories": [{"memory_id": "m1"}] Defensive patterns
Strategy: validation
Validate before calling
memories = cfg.get('model', {}).get('memories')
if memories is not None and not isinstance(memories, list):
cfg['model']['memories'] = [memories] Type guard
def has_list_memories(cfg: dict) -> bool:
m = cfg.get('model', {}).get('memories')
return m is None or isinstance(m, list) Try / catch
try:
ModelConfig.from_dict(data, path='agent')
except ConfigError as e:
if 'memories' in e.path and isinstance(data['model'].get('memories'), dict):
data['model']['memories'] = [data['model']['memories']]
ModelConfig.from_dict(data, path='agent')
else:
raise Prevention
- Use dash-item YAML lists under 'memories'
- Validate shape with a schema (jsonschema/pydantic) before handing dicts to from_dict
- Keep authoring helpers that always emit lists
When it happens
Trigger: Passing memories as a single dict (one attachment not wrapped in a list), a string, or other non-list value. Absent/null 'memories' skips validation entirely.
Common situations: Same single-object-vs-list mistake as tooling; YAML indentation that makes 'memories' a mapping instead of a sequence.
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
- model.name must be a non-empty string
- model.input_mode must be 'prompt' or 'messages'
- tooling must be a list
- file_types entries must be strings
- recursive must be boolean
AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27).
Data as JSON: /api/errors/e89eeb3bae4d53da.
Report an issue: GitHub.