github/spec-kit · error · TemplateResolutionError

Unknown template composition strategy '{strategy}' in {path}

Error message

Unknown template composition strategy '{strategy}' in {path}

What it means

Template layer composition only understands the strategies prepend, append, wrap, and replace (replace layers become the base). A layer manifest whose strategy string is anything else hits the final else-branch in compose_from_base() and raises TemplateResolutionError naming the unknown strategy and the layer file that declared it.

Source

Thrown at scripts/python/common.py:469

    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")
                if strategy == "prepend":
                    content = f"{layer_content}\n\n{content}"
                elif strategy == "append":
                    content = f"{content}\n\n{layer_content}"
                elif strategy == "wrap":
                    placeholder = "{CORE_TEMPLATE}"
                    if placeholder not in layer_content:
                        raise TemplateResolutionError(
                            f"Wrap layer {path} is missing {placeholder}"
                        )
                    content = layer_content.replace(placeholder, content)
                else:
                    raise TemplateResolutionError(
                        f"Unknown template composition strategy '{strategy}' in {path}"
                    )
        except (OSError, UnicodeError) as exc:
            raise TemplateResolutionError(
                f"Failed to read template layer for '{template_name}': {exc}"
            ) from exc
        return content

    override = (
        repo_root
        / ".specify"
        / "templates"
        / "overrides"
        / f"{template_name}.md"
    )
    if override.is_file():
        layers.append((override, "replace"))
        return compose_from_base()

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Open the layer file named in the error message, find its manifest, and set strategy to one of: replace, prepend, append, or wrap (lowercase, exact).
  2. Check for trailing whitespace or capitalization in the strategy value (e.g. 'Prepend', 'prepend ').
  3. Upgrade docs awareness: there is no 'merge' or 'concat' strategy — restructure the preset using prepend/append/wrap.

Example fix

# before (manifest.yaml)
strategy: pre-pend
# after
strategy: prepend
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = {"replace", "prepend", "append", "wrap"}

def strategy_is_valid(value) -> bool:
    return isinstance(value, str) and value in ALLOWED

# validate all manifests before resolution
assert all(strategy_is_valid(m.get("strategy")) for m in loaded_manifests)

Type guard

from typing import Any

ALLOWED = {"replace", "prepend", "append", "wrap"}

def is_strategy(value: Any) -> bool:
    """Narrow a manifest 'strategy' field to a known composition strategy."""
    return isinstance(value, str) and value in ALLOWED

Try / catch

try:
    content = resolve_template_content(name, repo_root)
except TemplateResolutionError as exc:
    if "Unknown template composition strategy" in str(exc):
        raise SystemExit(f"Fix the manifest named in: {exc}") from exc
    raise

Prevention

When it happens

Trigger: A manifest declares strategy: pre-pend, strategy: Wrap (case-sensitive), strategy: merge, or an empty/misspelled value; the layer loads fine but fails only at composition time, so the error message includes the specific path.

Common situations: Typos in hand-written preset manifests; strategy names copied from docs of a different tool version that supported extra strategies; trailing whitespace or a YAML quote issue making the value 'prepend ' with a trailing space.

Related errors


AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14). Data as JSON: /api/errors/193022e361037f3b. Report an issue: GitHub.