github/spec-kit · error · ValidationError
Invalid alias {alias!r} for command '{cmd['name']}': {alias_
Error message
Invalid alias {alias!r} for command '{cmd['name']}': {alias_reason} What it means
An alias string failed the same relative_extension_path_violation() policy used for command files (src/specify_cli/_utils.py:21): aliases are free-form but must remain safe relative output paths. Rejected shapes include absolute/anchored paths (leading '/', drive letters, UNC), '..' traversal segments, backslash separators, leading/trailing whitespace, empty values, and trailing directory slashes, plus platform-reserved components.
Source
Thrown at src/specify_cli/extensions/__init__.py:508
# Validate alias types; no pattern enforcement on aliases — they are
# intentionally free-form to preserve community extension compatibility
# (e.g. 'speckit.verify' short aliases used by existing extensions).
aliases = cmd.get("aliases")
if aliases is None:
cmd["aliases"] = []
aliases = []
if not isinstance(aliases, list):
raise ValidationError(
f"Aliases for command '{cmd['name']}' must be a list"
)
for alias in aliases:
if not isinstance(alias, str):
raise ValidationError(
f"Aliases for command '{cmd['name']}' must be strings"
)
alias_reason = relative_extension_path_violation(alias)
if alias_reason:
raise ValidationError(
f"Invalid alias {alias!r} for command "
f"'{cmd['name']}': {alias_reason}"
)
# Rewrite any hook command references that pointed at a renamed command or
# an alias-form ref (ext.cmd → speckit.ext.cmd). Always emit a warning when
# the reference is changed so extension authors know to update the manifest.
for hook_name, hook_data in self.data.get("hooks", {}).items():
for entry in coerce_hook_entries(hook_data):
if not isinstance(entry, dict):
raise ValidationError(
f"Hook '{hook_name}' must be a mapping or list of mappings, "
f"got {type(entry).__name__}"
)
command_ref = entry.get("command")
if not isinstance(command_ref, str):
continue
# Step 1: apply any rename from the auto-correction pass.View on GitHub (pinned to bf88c9f9a8)
Solutions
- Make the alias a plain relative slug with no slashes or '..' segments, e.g. "build" or "myext.build".
- Strip whitespace and drop any leading '/', drive letters, or backslashes.
- Audit third-party extension manifests for traversal-shaped aliases before installing them.
Example fix
// before "aliases": ["../commands/build"] // after "aliases": ["build"]
Defensive patterns
Strategy: validation
Validate before calling
from specify_cli._utils import relative_extension_path_violation
for c in manifest["provides"]["commands"]:
for a in (c.get("aliases") or []):
if isinstance(a, str):
reason = relative_extension_path_violation(a)
assert reason is None, f"unsafe alias {a!r}: {reason}" Type guard
def is_safe_alias(alias: str) -> bool:
from specify_cli._utils import relative_extension_path_violation
return relative_extension_path_violation(alias) is None Try / catch
try:
ExtensionManifest.load(path)
except ValidationError as e:
if "Invalid alias" in str(e):
# replace the traversal-shaped alias with a plain slug and retry
... Prevention
- Treat aliases as identifiers, not paths — no slashes or '..'.
- Audit third-party manifests for traversal-shaped aliases before install.
- Reuse the library's own relative_extension_path_violation() in CI lint.
When it happens
Trigger: "aliases": ["../evil"], "aliases": ["/etc/passwd"], "aliases": ["C:\\tmp"], or "aliases": ["build/"]. Raised in the per-alias loop right after the string-type check.
Common situations: Attempting path-traversal via an alias in a third-party extension (security gate); mistakenly treating the alias field as a file path; aliases ending in '/' copied from path constants.
Related errors
- Invalid command 'file' {label}: {reason}
- Invalid {singular} 'file' {label}: {reason}
- Invalid command alias {alias!r}: {alias_reason}
- Aliases for command '{cmd['name']}' must be a list
- Aliases for command '{cmd['name']}' must be strings
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/a74d175a39a4bfde.
Report an issue: GitHub.