{"record":{"id":"d274115d7d1eb867","repo":"github/spec-kit","slug":"wrap-layer-path-is-missing-placeholder","errorCode":null,"errorMessage":"Wrap layer {path} is missing {placeholder}","messagePattern":"Wrap layer (.+?) is missing (.+?)","errorType":"exception","errorClass":"TemplateResolutionError","httpStatus":null,"severity":"error","filePath":"scripts/python/common.py","lineNumber":464,"sourceCode":"    \"\"\"Resolve and compose template content through the project layer stack.\"\"\"\n    if not _is_safe_component(template_name):\n        return None\n\n    layers: list[tuple[Path, str]] = []\n\n    def compose_from_base() -> str:\n        try:\n            content = layers[-1][0].read_bytes().decode(\"utf-8\")\n            for path, strategy in reversed(layers[:-1]):\n                layer_content = path.read_bytes().decode(\"utf-8\")\n                if strategy == \"prepend\":\n                    content = f\"{layer_content}\\n\\n{content}\"\n                elif strategy == \"append\":\n                    content = f\"{content}\\n\\n{layer_content}\"\n                elif strategy == \"wrap\":\n                    placeholder = \"{CORE_TEMPLATE}\"\n                    if placeholder not in layer_content:\n                        raise TemplateResolutionError(\n                            f\"Wrap layer {path} is missing {placeholder}\"\n                        )\n                    content = layer_content.replace(placeholder, content)\n                else:\n                    raise TemplateResolutionError(\n                        f\"Unknown template composition strategy '{strategy}' in {path}\"\n                    )\n        except (OSError, UnicodeError) as exc:\n            raise TemplateResolutionError(\n                f\"Failed to read template layer for '{template_name}': {exc}\"\n            ) from exc\n        return content\n\n    override = (\n        repo_root\n        / \".specify\"\n        / \"templates\"\n        / \"overrides\"","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/scripts/python/common.py#L446-L482","documentation":"During template layer composition, a layer whose manifest declares strategy \"wrap\" must contain the literal placeholder {CORE_TEMPLATE} marking where the accumulated base content is inserted. If the wrap layer file lacks that token, composition cannot proceed and TemplateResolutionError is raised naming the layer path.","triggerScenarios":"A preset/override layer manifest sets strategy: wrap but the layer markdown file never includes {CORE_TEMPLATE}; or the placeholder was edited to {CORE-TEMPLATE}, {CORE_TEMPLATE } (extra spaces), or placed inside a code fence that was later reformatted away.","commonSituations":"Authoring a custom wrap preset and forgetting the placeholder; tools/editors that 'tidy' braces or template linters that strip unknown mustache-like tokens; renaming the placeholder during a copy-paste from another template system.","solutions":["Open the layer file named in the error and add the exact token {CORE_TEMPLATE} at the point where the base template content should be inserted.","Verify the spelling and that there are no surrounding spaces inside the braces ({CORE_TEMPLATE}, not { CORE_TEMPLATE }).","If you intended the layer to go before/after the base instead, change the manifest strategy to prepend or append, which need no placeholder."],"exampleFix":"# before — wrap layer body\n# My team header\n{CORE_TEMPLATE }\n# after\n# My team header\n{CORE_TEMPLATE}","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\ndef wrap_layer_is_valid(layer: Path) -> bool:\n    try:\n        return \"{CORE_TEMPLATE}\" in layer.read_text(encoding=\"utf-8\")\n    except OSError:\n        return False\n\n# before composing\nif any(s == \"wrap\" and not wrap_layer_is_valid(p) for p, s in wrap_layers):\n    print(\"wrap layer missing {CORE_TEMPLATE}; fix or downgrade to prepend\")","typeGuard":null,"tryCatchPattern":"try:\n    content = resolve_template_content(name, repo_root)\nexcept TemplateResolutionError as exc:\n    if \"missing {CORE_TEMPLATE}\" in str(exc):\n        raise SystemExit(f\"Fix the wrap layer named in: {exc}\") from exc\n    raise","preventionTips":["When authoring a wrap layer, add {CORE_TEMPLATE} first and build content around it.","Add an editor/CI grep test asserting the token exists in every file under presets marked strategy: wrap.","Prefer prepend/append strategies unless insertion-in-the-middle is truly required."],"tags":["templates","preset","composition","placeholder"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}