github/spec-kit · error · TemplateResolutionError
Failed to parse preset manifest {manifest_path}: {exc}
Error message
Failed to parse preset manifest {manifest_path}: {exc} What it means
Raised while resolving a template preset: the preset's manifest file (YAML) under the preset directory could not be read or parsed. The loader catches OSError, UnicodeError, ValueError, and yaml.YAMLError and re-raises them as TemplateResolutionError with the offending manifest path, so any unreadable, non-UTF-8, or syntactically invalid manifest surfaces here.
Source
Thrown at scripts/python/common.py:438
entry.get("name") != template_name
or entry.get("type", "template") != "template"
):
continue
file_value = entry.get("file", "")
strategy = entry.get("strategy", "replace")
relative = Path(file_value)
if (
not relative
or relative.is_absolute()
or ".." in relative.parts
):
return None
candidate = preset_dir / relative
if not candidate.is_file():
return None
return candidate, strategy.lower()
except (OSError, UnicodeError, ValueError, yaml.YAMLError) as exc:
raise TemplateResolutionError(
f"Failed to parse preset manifest {manifest_path}: {exc}"
) from exc
return (conventional, "replace") if conventional is not None else None
def resolve_template_content(template_name: str, repo_root: Path) -> str | None:
"""Resolve and compose template content through the project layer stack."""
if not _is_safe_component(template_name):
return None
layers: list[tuple[Path, str]] = []
def compose_from_base() -> str:
try:
content = layers[-1][0].read_bytes().decode("utf-8")
for path, strategy in reversed(layers[:-1]):
layer_content = path.read_bytes().decode("utf-8")View on GitHub (pinned to bf88c9f9a8)
Solutions
- Run python -c "import yaml,sys; yaml.safe_load(open(sys.argv[1]))" <manifest_path> to get the exact YAML error location and fix it.
- Confirm the file is valid UTF-8 (file <manifest> / re-save as UTF-8 without BOM).
- Check file permissions/readability of the preset directory if the message shows an OSError instead of a parser error.
- If the preset is not yours, delete or move the broken preset directory out of the preset stack so resolution skips it.
Example fix
# before (manifest.yaml — tab indentation breaks YAML) strategy: prepend # after strategy: prepend
Defensive patterns
Strategy: validation
Validate before calling
import yaml
from pathlib import Path
def manifest_is_loadable(path: Path) -> bool:
try:
raw = path.read_bytes().decode("utf-8")
value = yaml.safe_load(raw)
return isinstance(value, dict)
except (OSError, UnicodeError, ValueError, yaml.YAMLError):
return False
# skip broken presets before calling resolve_template_content
for m in preset_dir.glob("*/manifest.yaml"):
if not manifest_is_loadable(m):
print(f"skipping unreadable manifest: {m}") Try / catch
try:
content = resolve_template_content(name, repo_root)
except TemplateResolutionError as exc:
if "Failed to parse preset manifest" in str(exc):
logger.warning("skipping template %s: bad preset manifest (%s)", name, exc)
content = None
else:
raise Prevention
- Lint every preset manifest in CI with yaml.safe_load plus a schema check on strategy values.
- Keep preset files UTF-8 encoded without BOM.
- Add a unit test that loads all shipped manifests so a syntax error fails the build, not the user.
When it happens
Trigger: A preset directory (e.g. .specify/templates/presets/<name>/) contains a manifest.yaml with a YAML syntax error (bad indentation, unclosed quote, tabs), is saved in a non-UTF-8 encoding, or has file permissions that make read() raise OSError. Occurs whenever resolve_template_content() walks the preset layer stack and hits that manifest.
Common situations: Hand-editing a preset manifest and breaking YAML syntax; copying a preset from Windows with a BOM/latin-1 encoding; a manifest deleted or chmod'd between directory listing and read; CI checkout with mangled line endings producing an unparseable scalar.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unknown template composition strategy '{strategy}' in {path}
- Wrap layer {path} is missing {placeholder}
- Template '{template_name}' has composing layers but no repla
- Unknown event '{event_name}': must be one of {sorted(CANONIC
- Event '{event_name}' handler missing required non-empty 'com
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/e7a1a84d9da553ba.
Report an issue: GitHub.