github/spec-kit · error · SystemExit

ERROR: --template requires a template name

Error message

ERROR: --template requires a template name

What it means

_validate_safe_shared_directory() is the lenient validator that allows missing directories but still refuses symlinked components: any existing component on the path to the shared-infra directory that is a symlink raises SymlinkedSharedPathError. It is used by _ensure_safe_shared_destination(parent_must_exist=False) before writing files whose parents may not exist yet.

Source

Thrown at scripts/python/check_prerequisites.py:93

    index = 0
    while index < len(argv):
        arg = argv[index]
        if arg == "--json":
            json_mode = True
        elif arg == "--require-tasks":
            require_tasks = True
        elif arg == "--include-tasks":
            include_tasks = True
        elif arg == "--paths-only":
            paths_only = True
        elif arg == "--template":
            index += 1
            if index >= len(argv):
                print(
                    "ERROR: --template requires a template name",
                    file=sys.stderr,
                )
                raise SystemExit(1)
            template_name = argv[index]
        elif arg in {"--help", "-h"}:
            sys.stdout.write(HELP_TEXT)
            raise SystemExit(0)
        else:
            print(
                f"ERROR: Unknown option '{arg}'. Use --help for usage information.",
                file=sys.stderr,
            )
            raise SystemExit(1)
        index += 1

    return Args(
        json_mode=json_mode,
        require_tasks=require_tasks,
        include_tasks=include_tasks,
        paths_only=paths_only,
        template_name=template_name,

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Replace the symlink with a real directory (cp -aL to dereference, or rm the link and copy contents)
  2. Use the CLI's supported sharing mechanisms (presets, packages) instead of symlinking inside the tree
  3. Pre-check with p.is_symlink() down the parent chain before invoking the write
  4. Document to team members that .specify must be a real directory in this repo

Example fix

# before
$ ln -s ~/dotfiles/specify .specify && specify <cmd>  # raises

# after
$ rm .specify && cp -a ~/dotfiles/specify .specify && specify <cmd>
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def tree_free_of_symlinks(project: Path, rel_dir: Path) -> bool:
    cur = project
    for part in rel_dir.parts:
        cur = cur / part
        if cur.is_symlink():
            return False
    return True

assert tree_free_of_symlinks(project_path, rel_dir)

Try / catch

from specify_cli.shared_infra import SymlinkedSharedPathError

try:
    _validate_safe_shared_directory(project_path, directory)
except SymlinkedSharedPathError as e:
    raise SystemExit(f'replace symlink with a real directory: {e}') from e

Prevention

When it happens

Trigger: Writing a shared-infra file with parent_must_exist=False while any existing parent component (e.g. .specify or .specify/shared) is a symlink — e.g. a developer symlinking .specify to share configuration between clones.

Common situations: Dotfiles-style setups symlinking .specify; shared monorepo infra via symlinks; workspace tools (VS Code multi-root, devcontainers) that link config directories; restoring trees with backup tools that link instead of copy.

Related errors


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