github/spec-kit · error · ValidationError
Invalid provides.commands: expected a list
Error message
Invalid provides.commands: expected a list
What it means
If the provides mapping contains a commands key, its value must be a list. Each list element is a mapping describing one command (name, file); the type check runs before per-entry validation.
Source
Thrown at src/specify_cli/extensions/__init__.py:384
raise ValidationError(
"Invalid requires.speckit_version: expected a non-empty string, "
f"got {type(requires['speckit_version']).__name__}"
)
# Validate provides section
provides = self.data["provides"]
if not isinstance(provides, dict):
raise ValidationError(
f"Invalid provides: expected a mapping, got {type(provides).__name__}"
)
commands = provides.get("commands", [])
templates = provides.get("templates", [])
scripts = provides.get("scripts", [])
hooks = self.data.get("hooks")
events = self.data.get("events")
if "commands" in provides and not isinstance(commands, list):
raise ValidationError("Invalid provides.commands: expected a list")
if "templates" in provides and not isinstance(templates, list):
raise ValidationError("Invalid provides.templates: expected a list")
if "scripts" in provides and not isinstance(scripts, list):
raise ValidationError("Invalid provides.scripts: expected a list")
if "hooks" in self.data and not isinstance(hooks, dict):
raise ValidationError("Invalid hooks: expected a mapping")
if "events" in self.data:
from ..events import validate_events
validate_events(self.data)
has_commands = bool(commands)
has_hooks = bool(hooks)
has_events = bool(events)
has_templates = bool(templates)
has_scripts = bool(scripts)
if not has_commands and not has_hooks and not has_events and not has_templates and not has_scripts:
raise ValidationError(View on GitHub (pinned to bf88c9f9a8)
Solutions
- Wrap command entries in a list: prefix each with `- ` under commands.
- Even for a single command, use the list form.
- Ensure no stray quoting turns the whole value into a string.
Example fix
# before
provides:
commands:
name: check
file: commands/check.md
# after
provides:
commands:
- name: check
file: commands/check.md Defensive patterns
Strategy: validation
Validate before calling
def commands_list_ok(data: dict) -> bool:
provides = data.get("provides", {})
return "commands" not in provides or isinstance(provides["commands"], list) Prevention
- Every command entry starts with `- ` even when there is only one.
- Keep a list even for a single command; the mapping-only shorthand is invalid.
When it happens
Trigger: `provides:\n commands:` followed by a single mapping (not wrapped in a list), or a string like `commands: check`. isinstance(commands, list) fails.
Common situations: An extension with exactly one command where the author omits the list dash, so the single entry mapping sits where a list is expected.
Related errors
- Invalid requires: expected a mapping, got {type(requires).__
- Invalid provides: expected a mapping, got {type(provides).__
- Invalid provides.templates: expected a list
- Invalid provides.scripts: expected a list
- Invalid hooks: expected a mapping
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/802dc891a3e72702.
Report an issue: GitHub.