github/spec-kit · error · SystemExit

Error: branch_template must include the {number} token so ge

Error message

Error: branch_template must include the {number} token so generated branches remain valid feature branches.

What it means

_ensure_safe_shared_directory() was called with create=False, meaning it must only use directories that already exist, and a component of the shared-infra directory is missing. This is the non-creating validation mode used, for example, by _ensure_safe_shared_destination(parent_must_exist=True) before writing a file: the parent chain must already be in place.

Source

Thrown at extensions/git/scripts/python/create_new_feature_branch.py:374

        return template

    prefix = read_git_config_value(config_file, "branch_prefix")
    if not prefix:
        return ""
    if prefix.endswith("/"):
        return f"{prefix}{{number}}-{{slug}}"
    return f"{prefix}/{{number}}-{{slug}}"


def validate_branch_template(template: str) -> None:
    if not template:
        return
    if "{number}" not in template:
        _err(
            "Error: branch_template must include the {number} token so generated "
            "branches remain valid feature branches."
        )
        raise SystemExit(1)
    slug_index = template.find("{slug}")
    if slug_index != -1 and "{number}" in template[slug_index:]:
        _err(
            "Error: branch_template must not place {slug} before {number}; "
            "use {slug} only in the final feature segment."
        )
        raise SystemExit(1)
    feature_segment = template.rsplit("/", 1)[-1]
    if not feature_segment.startswith("{number}-"):
        _err(
            "Error: branch_template must put {number}- at the start of the final "
            "path segment so generated branches remain valid feature branches."
        )
        raise SystemExit(1)


def render_branch_template(
    template: str, feature_num: str, branch_suffix: str, author_token: str, app_token: str

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Recreate the directory tree first: let the install/setup flow (which uses create=True) run to completion before file writes
  2. If a previous step failed, rerun it or rerun `specify init` so the full directory skeleton is created
  3. Avoid deleting .specify subdirectories mid-flow; clean the whole tree and start over instead
  4. If orchestrating manually, mkdir -p the parent chain before invoking the write step

Example fix

# before: only the file-write step ran
_write_shared_text(proj, proj/'.specify'/'shared'/'scripts'/'s.sh', s)  # parent missing

# after: ensure skeleton exists first
_ensure_safe_shared_directory(proj, proj/'.specify'/'shared'/'scripts', create=True)
_write_shared_text(proj, proj/'.specify'/'shared'/'scripts'/'s.sh', s)
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def parent_chain_exists(project: Path, dest: Path) -> bool:
    return dest.parent.exists() and dest.parent.is_dir()

if not parent_chain_exists(project_path, dest):
    dest.parent.mkdir(parents=True, exist_ok=True)  # or run the full install step first

Try / catch

try:
    _ensure_safe_shared_destination(project_path, dest, parent_must_exist=True)
except ValueError as e:
    if 'does not exist' in str(e):
        dest.parent.mkdir(parents=True, exist_ok=True)
        _ensure_safe_shared_destination(project_path, dest, parent_must_exist=True)
    else:
        raise

Prevention

When it happens

Trigger: Writing a shared-infra file whose parent directory has not been created yet (e.g. .specify/shared/scripts missing at write time); deleting part of the .specify tree between install steps; running a step that assumes a previous step created the directory when it did not (interrupted init, failed prior command).

Common situations: Interrupted or partially failed `specify init`/install leaving .specify incomplete; manual cleanup with rm -rf .specify/* between operations; concurrent runs where one deleted directories the other expects; upgrading versions whose directory layout changed.

Related errors


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