github/spec-kit · error · ValidationError
Invalid hook '{hook_name}': list must contain at least one e
Error message
Invalid hook '{hook_name}': list must contain at least one entry What it means
When a hook's value is a list, that list must contain at least one entry. An explicitly empty list (`hook-name: []`) is treated as a declaration with no behavior, which validation rejects rather than silently installing a no-op hook.
Source
Thrown at src/specify_cli/extensions/__init__.py:415
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(
"Extension must provide at least one command, hook, or event "
"(or a declared template/script)"
)
self._validate_provided_artifacts(templates, section="templates", singular="template")
self._validate_provided_artifacts(scripts, section="scripts", singular="script")
# Validate hook values (if present).
# Each event is a single mapping or a list of mappings.
if hooks:
for hook_name, hook_config in hooks.items():
if isinstance(hook_config, list) and not hook_config:
raise ValidationError(
f"Invalid hook '{hook_name}': list must contain at least one entry"
)
for entry in coerce_hook_entries(hook_config):
if not isinstance(entry, dict):
raise ValidationError(
f"Invalid hook '{hook_name}': "
"expected a mapping or list of mappings"
)
if not entry.get("command"):
raise ValidationError(
f"Hook '{hook_name}' missing required 'command' field"
)
if "priority" in entry:
priority = entry["priority"]
if not isinstance(priority, int) or isinstance(priority, bool):
raise ValidationError(
f"Hook '{hook_name}' has invalid 'priority': "
"must be an integer"View on GitHub (pinned to bf88c9f9a8)
Solutions
- Delete the hook key entirely if you don't want the hook.
- Or populate the list with at least one mapping: `- command: ./script.sh`.
- Don't use an empty list as a 'disabled' marker — the schema has no such concept.
Example fix
# before
hooks:
post-install: []
# after (omit it, or provide an entry)
# hooks:
# post-install: []
# or
hooks:
post-install:
- command: ./setup.sh Defensive patterns
Strategy: validation
Validate before calling
def hook_lists_nonempty(data: dict) -> bool:
hooks = data.get("hooks") or {}
return all(not isinstance(v, list) or len(v) > 0 for v in hooks.values()) Prevention
- Delete a hook key to disable it; empty lists are invalid, not 'off'.
- When templating manifests, strip unused hooks rather than emitting `[]`.
When it happens
Trigger: `hooks:\n post-install: []` — hook_config is a list and `not hook_config` is true, so the error names the hook.
Common situations: Author disables a hook by emptying its list instead of deleting the key, or a generator template emits empty lists for unconfigured hooks.
Related errors
- Invalid hooks: expected a mapping
- Invalid hook '{hook_name}': expected a mapping or list of ma
- Hook '{hook_name}' missing required 'command' field
- Hook '{hook_name}' has invalid 'priority': must be an intege
- Invalid extension ID '{ext['id']}': must be lowercase alphan
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/dd810b6afedbfe3f.
Report an issue: GitHub.