github/spec-kit · error · PresetValidationError
Invalid command name '{tmpl['name']}': must be lowercase alp
Error message
Invalid command name '{tmpl['name']}': must be lowercase alphanumeric with hyphens and dots only What it means
Template entries with `type: command` must have a `name` matching ^[a-z0-9.-]+$ — lowercase letters, digits, hyphens, and dots (dot notation like `speckit.build`). Any uppercase letter, underscore, space, or other character fails this regex check during manifest validation.
Source
Thrown at src/specify_cli/presets/__init__.py:476
# Persist normalized value so downstream code sees lowercase
if "strategy" in tmpl:
tmpl["strategy"] = strategy
if strategy not in VALID_PRESET_STRATEGIES:
raise PresetValidationError(
f"Invalid strategy '{strategy}': "
f"must be one of {sorted(VALID_PRESET_STRATEGIES)}"
)
if tmpl["type"] == "script" and strategy not in VALID_SCRIPT_STRATEGIES:
raise PresetValidationError(
f"Invalid strategy '{strategy}' for script: "
f"scripts only support {sorted(VALID_SCRIPT_STRATEGIES)}"
)
# Validate template name format
if tmpl["type"] == "command":
# Commands use dot notation (e.g. speckit.specify)
if not re.match(r'^[a-z0-9.-]+$', tmpl["name"]):
raise PresetValidationError(
f"Invalid command name '{tmpl['name']}': "
"must be lowercase alphanumeric with hyphens and dots only"
)
else:
if not re.match(r'^[a-z0-9-]+$', tmpl["name"]):
raise PresetValidationError(
f"Invalid template name '{tmpl['name']}': "
"must be lowercase alphanumeric with hyphens only"
)
@property
def id(self) -> str:
"""Get preset ID."""
return self.data["preset"]["id"]
@property
def name(self) -> str:
"""Get preset name."""View on GitHub (pinned to bf88c9f9a8)
Solutions
- Rename the command to kebab-case or dot notation: `speckit.build-all`, `speckit.build`.
- Replace underscores with hyphens and lowercase everything.
- Re-run the preset install after fixing preset.yml.
Example fix
# before
- name: speckit.build_all
type: command
# after
- name: speckit.build-all
type: command Defensive patterns
Strategy: validation
Validate before calling
import re
for t in yaml.safe_load(open("preset.yml")).get("templates", []):
if t.get("type") == "command":
assert re.fullmatch(r"[a-z0-9.-]+", t["name"]), f"bad command name {t['name']!r}" Type guard
import re
def is_valid_command_name(name: str) -> bool:
return bool(re.fullmatch(r"[a-z0-9.-]+", name)) Try / catch
try:
manager.install_from_directory(src, version)
except PresetValidationError as e:
if "Invalid command name" in str(e):
# convert to lowercase kebab/dot notation and retry
... Prevention
- Command names: lowercase letters, digits, hyphens, dots only (dot notation like speckit.build).
- No underscores or uppercase — convert snake_case to kebab-case.
- Add a preset.yml lint step to your preset's CI.
When it happens
Trigger: A preset.yml command template named `speckit.build_all`, `Speckit.Build`, or `speckit build` (space). The check runs on every command-type template during PresetManifest validation, i.e. at install time.
Common situations: Using snake_case command names (common in other CLI conventions), capitalized names, or names copied from filenames with spaces. The dot is allowed specifically because commands use dot notation (e.g. speckit.specify).
Related errors
- Invalid template name '{tmpl['name']}': must be lowercase al
- Event '{event_name}' missing required 'command' string
- Invalid extension ID '{ext['id']}': must be lowercase alphan
- Invalid strategy value: must be a string, got {type(strategy
- Invalid strategy '{strategy}': must be one of {sorted(VALID_
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/dbefca010c90d98a.
Report an issue: GitHub.