github/spec-kit · error · BundlerError

Step '{component.id}' installs from a catalog and network ac

Error message

Step '{component.id}' installs from a catalog and network access is disabled; re-run without --offline or install it first with 'specify workflow step add {component.id}'.

What it means

Step components have no bundled/local path at all in this bundler version — _StepKindManager.install() unconditionally requires network (there is no _is_bundled escape hatch like workflows have). With allow_network=False the install is refused before delegating to `specify workflow step add`.

Source

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


class _StepKindManager:
    def __init__(self, project_root: Path, allow_network: bool) -> None:
        from ...workflows.catalog import StepRegistry

        self._root = project_root
        self._allow_network = allow_network
        self._registry = StepRegistry(project_root)

    def is_installed(self, component: ComponentRef) -> bool:
        try:
            return self._registry.is_installed(component.id)
        except Exception:  # noqa: BLE001
            return False

    def install(self, component: ComponentRef) -> None:
        if not self._allow_network:
            raise BundlerError(
                f"Step '{component.id}' installs from a catalog and network access "
                f"is disabled; re-run without --offline or install it first with "
                f"'specify workflow step add {component.id}'."
            )
        from ... import workflow_step_add

        with _chdir(self._root):
            _delegate_command(
                "install", f"step '{component.id}'",
                lambda: workflow_step_add(component.id),
            )

    def refresh(self, component: ComponentRef) -> None:
        # Preserve an existing step until we've validated we can perform refresh.
        # For already-installed steps, keep a backup and restore it if the
        # remove+reinstall path fails.
        if not (self._allow_network and self.is_installed(component)):
            self.install(component)

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Pre-install the step online once: `specify workflow step add <id>`, then re-run the offline bundle install.
  2. Run the bundle install without --offline.
  3. For permanently offline environments, remove the step from the bundle or request/upgrade to a specify_cli version that vendors steps into artifacts.

Example fix

specify workflow step add my-step   # once, with network
specify bundle install my-bundle-1.0.0.zip --offline
Defensive patterns

Strategy: validation

Validate before calling

# Steps have NO offline path in this version — pre-install is mandatory
from specify_cli.workflows.catalog import StepRegistry

registry = StepRegistry(project_root)
missing = [c.id for c in plan.components if c.kind == "steps" and not registry.is_installed(c.id)]
if missing and running_offline:
    print(f"steps require network or pre-install: {missing}"); exit(1)

Try / catch

from specify_cli.bundler.core import BundlerError

try:
    install_bundle(project_root, plan, installer, allow_network=False)
except BundlerError as exc:
    if "network access is disabled" in str(exc) and "Step" in str(exc):
        subprocess.run(["specify", "workflow", "step", "add", extract_id(str(exc))], check=True)
        install_bundle(project_root, plan, installer, allow_network=False)

Prevention

When it happens

Trigger: Any `specify bundle install --offline` whose manifest contains a kind: steps component. Unlike workflows, steps always fetch from a catalog, so the offline guard raises immediately at primitives.py:397.

Common situations: Offline CI pipelines with bundles that include steps; users assuming steps behave like workflows (which can be vendored) and hitting the stricter rule.

Related errors


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