github/spec-kit · error · PresetValidationError
Invalid extension registry {registry.registry_path}: refusin
Error message
Invalid extension registry {registry.registry_path}: refusing to enumerate extensions What it means
The extensions registry file is corrupt and enumeration fails closed: ExtensionRegistry._load() would silently normalize an unreadable registry to empty, which would let every on-disk extension directory be treated as unregistered-and-enabled — a fail-open path that could inject constitution content. The presets layer therefore raises PresetValidationError and refuses to enumerate.
Source
Thrown at src/specify_cli/presets/__init__.py:5132
Registered extensions use their stored priority; unregistered directories
get implicit priority=10. Results are sorted by (priority, ext_id) for
deterministic ordering.
Returns:
List of (priority, ext_id, metadata_or_none) tuples sorted by priority.
"""
if not self.extensions_dir.exists():
return []
registry = ExtensionRegistry(self.extensions_dir)
# Fail closed on a corrupt registry. ExtensionRegistry._load() recovers
# by normalizing an unreadable registry to an empty mapping, which would
# otherwise cause the directory scan below to admit every on-disk
# directory as an unregistered, enabled extension — a fail-open path
# that could supply constitution content from an invalid registry state.
if registry.is_corrupt():
raise PresetValidationError(
f"Invalid extension registry {registry.registry_path}: "
"refusing to enumerate extensions"
)
# Use keys() to track ALL extensions (including corrupted entries) without deep copy
# This prevents corrupted entries from being picked up as "unregistered" dirs
registered_extension_ids = registry.keys()
# Get all registered extensions including disabled; we filter disabled manually below
all_registered = registry.list_by_priority(include_disabled=True)
all_extensions: list[tuple[int, str, dict | None]] = []
# Only include enabled extensions in the result
for ext_id, metadata in all_registered:
if not self._is_safe_registry_id(ext_id):
continue
# Skip disabled extensions
if not metadata.get("enabled", True):View on GitHub (pinned to bf88c9f9a8)
Solutions
- Inspect the registry file (registry.registry_path) and fix its JSON syntax or structure
- If unrecoverable, restore it from version control or delete it so it is rebuilt from the on-disk extension state
- Avoid editing the registry while spec-kit commands run; keep writes atomic
- Re-run the enumeration after repair to confirm is_corrupt() is False
Example fix
# before (registry.json truncated)
{"extensions": {"agent-context": {"prior
# after
{"extensions": {"agent-context": {"priority": 100, "enabled": true}}} Defensive patterns
Strategy: try-catch
Validate before calling
from specify_cli.extensions import ExtensionRegistry
reg = ExtensionRegistry(extensions_dir)
if reg.is_corrupt():
repair_or_restore_registry(reg.registry_path) # fix JSON or restore from VCS Try / catch
try:
exts = enumerate_extensions(manager)
except PresetValidationError as e:
if "Invalid extension registry" in str(e):
restore_registry_from_backup(extensions_dir) # then retry once
else:
raise Prevention
- Keep .specify/extensions registry in version control for easy restore
- Never hand-edit the registry JSON while spec-kit commands are running
- Treat registry corruption as fail-closed: repair before enumerating, do not bypass the check
When it happens
Trigger: Calling the extension-enumeration flow while .specify/extensions registry JSON is malformed (truncated write, invalid JSON, wrong structure) so registry.is_corrupt() returns True.
Common situations: Concurrent writes or a killed process truncating the registry file; hand-editing the registry JSON; partial sync/merge of the .specify directory; disk corruption.
Related errors
- Extension '{ext_spec}' is in the '{catalog_name}' catalog bu
- Invalid command 'file' {label}: {reason}
- Invalid alias {alias!r} for command '{cmd['name']}': {alias_
- Invalid {singular} 'file' {label}: {reason}
- Extension '{extension_id}' is not installed
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/e45e8a1d50f8869f.
Report an issue: GitHub.