github/spec-kit · error · ValueError

No runnable script variant for this platform: requested {req

Error message

No runnable script variant for this platform: requested {requested!r}; available: {available}

What it means

IntegrationBase.select_script_variant picks the script variant (sh/ps/py) for a command template. It first honors the requested variant if present in script_commands (the variants the template's scripts: frontmatter actually provides); otherwise it falls back to the platform native variant (ps on Windows, sh elsewhere), then the cross-platform py, and only then gives up with this error. Seeing it means script_commands contained none of the viable candidates — i.e. the template declared no (or only the wrong) script variants.

Source

Thrown at src/specify_cli/integrations/base.py:731

        """Select the requested variant or a runnable platform fallback."""
        if isinstance(requested, str) and requested in script_commands:
            return requested

        platform_variant = (
            "ps" if platform.system().lower().startswith("win") else "sh"
        )
        secondary_variant = "sh" if platform_variant == "ps" else "ps"
        fallbacks = (
            (platform_variant, "py")
            if requested == "py"
            else (platform_variant, secondary_variant, "py")
        )
        for candidate in fallbacks:
            if candidate in script_commands:
                return candidate

        available = ", ".join(sorted(script_commands)) or "none"
        raise ValueError(
            "No runnable script variant for this platform: "
            f"requested {requested!r}; available: {available}"
        )

    @staticmethod
    def _interpreter_runs(path: str) -> bool:
        """Return True when *path* executes as a Python interpreter.

        Runs isolated (``-I``) without ``site`` (``-S``) and discards
        I/O so the probe is a fast liveness check that cannot trigger
        ``sitecustomize``/user startup hooks.
        """
        try:
            return (
                subprocess.run(
                    [path, "-I", "-S", "-c", ""],
                    stdin=subprocess.DEVNULL,
                    stdout=subprocess.DEVNULL,

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Add a complete scripts: frontmatter to the template with sh, ps, and py entries (all three are required by the parity rule).
  2. Check the reported 'available:' list — it shows exactly which variant keys the template did declare; fix typos like 'bash' -> 'sh'.
  3. If the template genuinely needs no script, route it through the template path that skips select_script_variant instead of calling it unconditionally.

Example fix

# before (templates/commands/my-command.md)
---
description: "Broken"
---
# after
---
description: "Fixed"
scripts:
  sh: scripts/bash/my-command.sh
  ps: scripts/powershell/my-command.ps1
  py: scripts/python/my_command.py
---
Defensive patterns

Strategy: validation

Validate before calling

from specify_cli.integrations.base import IntegrationBase

variant = IntegrationBase.select_script_variant(
    requested, {k: v for k, v in script_commands.items()}
)  # raises with the 'available:' list if unsatisfiable — call it early to fail fast

Type guard

def has_runnable_variant(script_commands: dict[str, str]) -> bool:
    import platform
    native = "ps" if platform.system().lower().startswith("win") else "sh"
    secondary = "sh" if native == "ps" else "ps"
    return bool(script_commands) and any(
        v in script_commands for v in (native, secondary, "py")
    )

Try / catch

try:
    variant = IntegrationBase.select_script_variant(requested, script_commands)
except ValueError as exc:
    raise SystemExit(
        f"template provides no runnable script variants ({exc}); "
        "add sh/ps/py entries to its scripts: frontmatter"
    ) from None

Prevention

When it happens

Trigger: A command template whose scripts: frontmatter is missing or lists no sh/ps/py entries that match the platform fallbacks — e.g. only a 'ps' entry while running on Linux is fine (secondary fallback), but an empty or typo'd variant key set ('shell', 'bash') yields an empty/foreign script_commands dict; requesting a variant like 'py' when the template provides only variants outside the fallback chain.

Common situations: Custom or forked command templates that omit the scripts: frontmatter required by the parity rule; templates that use non-canonical keys; a template intentionally having no script (constitution/specify style) being processed through a path that expects one.

Related errors


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