github/spec-kit · error · ValidationError
Extension ID '{manifest.id}' conflicts with core command nam
Error message
Extension ID '{manifest.id}' conflicts with core command namespace '{manifest.id}' What it means
During command-registration validation, the extension's own ID collided with CORE_COMMAND_NAMES — the set of built-in speckit command names (analyze, checklist, clarify, constitution, converge, implement, plan, specify, tasks, taskstoissues, loaded at extensions/__init__.py:119 with a hardcoded fallback). An extension whose id equals a core command name would let it shadow or collide with core slash-commands, so the whole manifest is rejected before any of its commands are registered.
Source
Thrown at src/specify_cli/extensions/__init__.py:1096
Performs install-time validation for extension-specific constraints:
- primary commands must use the canonical `speckit.{extension}.{command}` shape
- primary commands must use this extension's namespace
- command namespaces must not shadow core commands
- duplicate command/alias names inside one manifest are rejected
- aliases are free-form but must remain safe relative output paths
Args:
manifest: Parsed extension manifest
Returns:
Mapping of declared command/alias name -> kind ("command"/"alias")
Raises:
ValidationError: If any declared name is invalid
"""
if manifest.id in CORE_COMMAND_NAMES:
raise ValidationError(
f"Extension ID '{manifest.id}' conflicts with core command namespace '{manifest.id}'"
)
declared_names: Dict[str, str] = {}
for cmd in manifest.commands:
primary_name = cmd["name"]
aliases = cmd.get("aliases", [])
if aliases is None:
aliases = []
if not isinstance(aliases, list):
raise ValidationError(
f"Aliases for command '{primary_name}' must be a list"
)
for kind, name in [("command", primary_name)] + [
("alias", alias) for alias in aliasesView on GitHub (pinned to bf88c9f9a8)
Solutions
- Rename the extension id to something unique and non-core, e.g. 'plan-enhancer' instead of 'plan', and update all speckit.{id}.{cmd} command names and references to match.
- After renaming the id, re-check every command name follows speckit.<new-id>.<cmd>.
- If you hit this after a Spec Kit upgrade, check the current core command list and rename the colliding extension.
Example fix
// before (manifest)
{ "id": "plan", "commands": [{ "name": "speckit.plan.run", "file": "commands/run.md" }] }
// after
{ "id": "plan-enhancer", "commands": [{ "name": "speckit.plan-enhancer.run", "file": "commands/run.md" }] } Defensive patterns
Strategy: validation
Validate before calling
from specify_cli.extensions import CORE_COMMAND_NAMES
if manifest["id"] in CORE_COMMAND_NAMES:
raise SystemExit(f"id '{manifest['id']}' is reserved; rename the extension") Type guard
def extension_id_is_safe(ext_id: str) -> bool:
from specify_cli.extensions import CORE_COMMAND_NAMES
return ext_id not in CORE_COMMAND_NAMES Try / catch
try:
ExtensionManifest.load(path) # or command registration path
except ValidationError as e:
if "conflicts with core command namespace" in str(e):
# rename the extension id and all speckit.<old-id>.* command names, then retry
... Prevention
- Avoid generic ids matching core commands: plan, specify, implement, analyze, clarify, converge, tasks, checklist, constitution, taskstoissues.
- Prefix ids with your org/tool name (myorg-plan) to avoid collisions.
- After a Spec Kit upgrade, re-check CORE_COMMAND_NAMES for newly reserved names.
When it happens
Trigger: An extension manifest with "id": "plan" or "id": "specify". The check runs at the top of the declared-names builder (extensions/__init__.py:1096) during command registration for the extension.
Common situations: Generic extension ids like 'plan', 'tasks', or 'analyze' chosen without checking the reserved list; forks renaming an extension to a short core word; core set grown in a newer Spec Kit version so a previously-acceptable id becomes reserved after upgrade.
Related errors
- Invalid command name '{cmd['name']}': must follow pattern 's
- Invalid {singular} name '{name}': must be lowercase alphanum
- Manifest must be a YAML mapping, got {type(data).__name__}:
- Missing required field: {field}
- Invalid extension: expected a mapping, got {type(ext).__name
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/759604524caf8ef9.
Report an issue: GitHub.