github/spec-kit · error · BundlerError

Unknown component kind '{kind}'.

Error message

Unknown component kind '{kind}'.

What it means

primitive_manager() dispatches component installs by kind and only recognizes the strings 'presets', 'extensions', 'workflows', and 'steps'. Any other kind string reaches the fall-through and raises immediately, before any manager is constructed.

Source

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

    def refresh(self, component: ComponentRef) -> None:
        pass

    def remove(self, component: ComponentRef) -> None:
        pass


def primitive_manager(
    kind: str, project_root: Path, *, allow_network: bool = True
) -> _KindManager:
    if kind == "presets":
        return _PresetKindManager(project_root, allow_network)
    if kind == "extensions":
        return _ExtensionKindManager(project_root, allow_network)
    if kind == "workflows":
        return _WorkflowKindManager(project_root, allow_network)
    if kind == "steps":
        return _StepKindManager(project_root, allow_network)
    raise BundlerError(f"Unknown component kind '{kind}'.")


@contextlib.contextmanager
def _chdir(path: Path):
    """Temporarily switch the working directory.

    The delegated workflow/step command callables resolve the project via
    ``Path.cwd()``; this makes that resolution land on *path*.
    """
    previous = Path.cwd()
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(previous)


def _delegate_command(action: str, label: str, call) -> None:

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Change the kind in bundle.yml to one of the exact plural forms: presets, extensions, workflows, steps.
  2. Check for typos and singular/plural confusion ('preset' → 'presets').
  3. If you genuinely need a new component type, upgrade specify_cli — the supported set may have grown in a newer release.
  4. Run `specify bundle validate` to catch this before install.

Example fix

# before (bundle.yml)
components:
  - kind: preset
    id: my-preset

# after
components:
  - kind: presets
    id: my-preset
Defensive patterns

Strategy: type-guard

Validate before calling

SUPPORTED_KINDS = {"presets", "extensions", "workflows", "steps"}
assert component.kind in SUPPORTED_KINDS, f"kind must be one of {sorted(SUPPORTED_KINDS)}"

Type guard

def is_supported_kind(kind: str) -> bool:
    """Type guard matching primitive_manager()'s dispatch table."""
    return kind in {"presets", "extensions", "workflows", "steps"}

Try / catch

from specify_cli.bundler.core import BundlerError

try:
    manager = primitive_manager(kind, project_root)
except BundlerError as exc:
    if "Unknown component kind" in str(exc):
        raise ValueError(f"fix bundle.yml: {exc}") from exc

Prevention

When it happens

Trigger: A bundle.yml or caller-supplied ComponentRef with kind set to something else — e.g. singular forms ('preset', 'extension'), 'skills', 'commands', or a typo — passed into primitive_manager() or into a bundle install that routes components by kind.

Common situations: Bundle authors using singular kind names; manifests written against a different tool's schema; new component types expected after a spec-kit upgrade that this version does not support; simple typos.

Related errors


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