github/spec-kit · error · BundlerError

Failed to {action} {label}.

Error message

Failed to {action} {label}.

What it means

The bundler delegates component install/remove to existing typer CLI commands (e.g. workflow_add). Those commands signal failure by raising typer.Exit with a non-zero exit_code; _delegate_command translates that into a BundlerError naming the action and label. The underlying command's own error output was already printed to the console.

Source

Thrown at src/specify_cli/bundler/services/primitives.py:139

    """
    previous = Path.cwd()
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(previous)


def _delegate_command(action: str, label: str, call) -> None:
    """Run a delegated CLI command callable, translating its exit into errors."""
    import typer

    try:
        call()
    except typer.Exit as exc:  # raised by the delegated command on failure
        code = getattr(exc, "exit_code", 0) or 0
        if code != 0:
            raise BundlerError(f"Failed to {action} {label}.") from exc
    except SystemExit as exc:  # pragma: no cover - defensive
        if exc.code not in (0, None):
            raise BundlerError(f"Failed to {action} {label}.") from exc


class _PresetKindManager:
    def __init__(self, project_root: Path, allow_network: bool) -> None:
        from ...presets import PresetManager

        self._root = project_root
        self._allow_network = allow_network
        self._manager = PresetManager(project_root)

    def is_installed(self, component: ComponentRef) -> bool:
        try:
            return self._manager.get_pack(component.id) is not None
        except Exception:  # noqa: BLE001
            return False

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Scroll up in the output: the delegated command printed its own error message before typer.Exit — that names the real failure.
  2. Run the delegated command directly to reproduce: `specify workflow add <id>` or `specify workflow step add <id>`.
  3. If the id is wrong, fix it in bundle.yml, validate, rebuild, and reinstall.
  4. If it is a network/catalog failure, fix connectivity or pre-install the component, then re-run the bundle install.
Defensive patterns

Strategy: try-catch

Validate before calling

# Verify the component resolves before bundling it
from specify_cli.workflows.catalog import WorkflowRegistry

registry = WorkflowRegistry(project_root)
if not registry.is_installed(workflow_id):
    # ensure catalog can serve it — the delegated `workflow add` will need it
    pass

Try / catch

from specify_cli.bundler.core import BundlerError

try:
    install_bundle(project_root, plan, installer)
except BundlerError as exc:
    if str(exc).startswith("Failed to install workflow") or "Failed to " in str(exc):
        # delegated command already printed its real error above — surface it
        show_last_command_output()

Prevention

When it happens

Trigger: Installing or removing a workflow/step component through a bundle where the delegated command (workflow_add(component.id), workflow_step_add(component.id), or a remove equivalent) fails — bad id, network failure fetching from the catalog, or a validation failure inside the command.

Common situations: A bundle references a workflow/step id that does not exist in the catalog; the catalog is unreachable when the delegated command tries to download; the workflow fails its own install-time checks.

Related errors


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