OpenBMB/ChatDev · error · ConfigError

node config block required

Error message

node config block required

What it means

NodeConfig.from_dict requires a non-null 'config' key in the node mapping, since every node type needs its type-specific config payload. Missing or null 'config' raises this ConfigError with path '<node>.config'.

Source

Thrown at entity/configs/node/node.py:198

        description = optional_str(mapping, "description", path)
        # keep_context = bool(mapping.get("keep_context", False))
        log_output = bool(mapping.get("log_output", True))
        context_window = int(mapping.get("context_window", 0))
        input_value = ensure_list(mapping.get("input"))
        output_value = ensure_list(mapping.get("output"))

        input_messages: List[Message] = []
        for value in input_value:
            if isinstance(value, dict) and "role" in value:
                input_messages.append(Message.from_dict(value))
            elif isinstance(value, Message):
                input_messages.append(value)
            else:
                input_messages.append(Message(role=MessageRole.USER, content=str(value)))

        if "config" not in mapping or mapping["config"] is None:
            raise ConfigError("node config block required", extend_path(path, "config"))
        config_obj = schema.config_cls.from_dict(
            mapping["config"], path=extend_path(path, "config")
        )

        formatted_output: List[NodePayload] = []
        for value in output_value:
            if isinstance(value, dict) and "role" in value:
                formatted_output.append(Message.from_dict(value))
            elif isinstance(value, Message):
                formatted_output.append(value)
            else:
                formatted_output.append(
                    Message(role=MessageRole.ASSISTANT, content=str(value))
                )

        # Dynamic configuration parsing removed - dynamic is now on edges

        node = cls(

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Add a config mapping appropriate to the node type, e.g. config: {} if no options are needed
  2. Copy the config block from a working example for that node type
  3. Pre-validate graph configs with a schema check before submission

Example fix

# before
- id: n1
  type: python_runner
# after
- id: n1
  type: python_runner
  config:
    timeout_seconds: 60
Defensive patterns

Strategy: validation

Validate before calling

for n in cfg.get('nodes', []):
    if not isinstance(n.get('config'), dict):
        n['config'] = {}  # or raise

Try / catch

try:
    NodeConfig.from_dict(data, path='nodes[0]')
except ConfigError as e:
    if 'node config block required' in str(e):
        data['config'] = {}
        NodeConfig.from_dict(data, path='nodes[0]')

Prevention

When it happens

Trigger: Defining a node with id/type but no config block, or config: null, in a graph definition passed to from_dict (directly or via add_successor).

Common situations: Skeleton configs where the config block was left as a TODO; minimal test nodes; migrations or linters that strip 'empty' blocks.

Related errors


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