OpenBMB/ChatDev · error · ConfigError

skill name is required

Error message

skill name is required

What it means

AgentSkillSelectionConfig.from_dict requires a non-empty 'name' string for each skill selection entry; missing, non-string, or whitespace-only names raise ConfigError('skill name is required') at '<path>.name'. It is called from _coerce_allow_entries when parsing allow-list entries.

Source

Thrown at entity/configs/node/skills.py:85

class AgentSkillSelectionConfig(BaseConfig):
    name: str

    FIELD_SPECS = {
        "name": ConfigFieldSpec(
            name="name",
            display_name="Skill Name",
            type_hint="str",
            required=True,
            description="Discovered skill name from the default repo-level skills directory.",
        ),
    }

    @classmethod
    def from_dict(cls, data: Mapping[str, Any], *, path: str) -> "AgentSkillSelectionConfig":
        mapping = require_mapping(data, path)
        name = mapping.get("name")
        if not isinstance(name, str) or not name.strip():
            raise ConfigError("skill name is required", extend_path(path, "name"))
        return cls(name=name.strip(), path=path)

    @classmethod
    def field_specs(cls) -> Dict[str, ConfigFieldSpec]:
        specs = super().field_specs()
        name_spec = specs.get("name")
        if name_spec is None:
            return specs

        discovered = _discover_default_skills()
        enum_values = [name for name, _ in discovered] or None
        enum_options = [
            EnumOption(value=name, label=name, description=description)
            for name, description in discovered
        ] or None
        description = name_spec.description or "Skill name"
        if not discovered:
            description = (

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Ensure each mapping entry has a non-empty 'name' key
  2. Use plain string entries for simple cases: allow: [my-skill]
  3. Strip placeholder entries that have no name

Example fix

# before
allow:
  - description: helper
# after
allow:
  - name: helper
    description: helper
Defensive patterns

Strategy: validation

Validate before calling

for entry in allow_list:
    if isinstance(entry, dict):
        assert isinstance(entry.get('name'), str) and entry['name'].strip()

Type guard

def is_valid_skill_entry(e) -> bool:
    return (isinstance(e, str) and e.strip()) or (isinstance(e, dict) and isinstance(e.get('name'), str) and e['name'].strip())

Try / catch

try:
    cfg = SkillsConfig.from_dict(d, path='skills')
except ConfigError as e:
    if 'skill name is required' in str(e):
        d['allow'] = [e for e in d.get('allow', []) if isinstance(e, str) or (isinstance(e, dict) and e.get('name'))]
        cfg = SkillsConfig.from_dict(d, path='skills')

Prevention

When it happens

Trigger: An allow-list skill entry mapping like {} or {name: ' '} or {name: 123} in the skills config.

Common situations: YAML entries with a typo'd key (nane:), entries that only have other keys like {path: ...}, or trimmed/empty names from templating.

Related errors


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