github/spec-kit · error · BundlerError

No bundle.yml found in '{candidate}'.

Error message

No bundle.yml found in '{candidate}'.

What it means

_local_manifest_source(arg) treats an existing directory argument as a bundle directory and requires <dir>/bundle.yml. This branch fired because the directory exists but bundle.yml does not, and it raises (rather than returning None) precisely because the user clearly intended a local bundle at that path.

Source

Thrown at src/specify_cli/commands/bundle/__init__.py:771


def _local_manifest_source(arg: str):
    """Return a :class:`BundleManifest` if *arg* points at a local bundle.

    Supports a built ``.zip`` artifact, a bundle directory, or a ``bundle.yml``
    file. Returns ``None`` when *arg* is not an existing path, so callers fall
    back to catalog-stack resolution by bundle id.
    """
    from ...bundler.models.manifest import BundleManifest

    candidate = Path(arg).expanduser()
    if not candidate.exists():
        return None

    if candidate.is_dir():
        manifest_path = candidate / "bundle.yml"
        if not manifest_path.exists():
            raise BundlerError(f"No bundle.yml found in '{candidate}'.")
        return BundleManifest.from_file(manifest_path)

    if candidate.suffix == ".zip":
        import yaml as _yaml

        from ..._download_security import open_zip_bounded, read_zip_member_limited

        with open_zip_bounded(candidate, error_type=BundlerError) as archive:
            try:
                archive.getinfo("bundle.yml")
            except KeyError as exc:
                raise BundlerError(
                    f"Artifact '{candidate}' does not contain a bundle.yml."
                ) from exc
            raw = read_zip_member_limited(
                archive,
                "bundle.yml",
                error_type=BundlerError,

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Create or rename the manifest so <dir>/bundle.yml exists (exact name, .yml not .yaml).
  2. Pass the manifest file directly: specify bundle install ./my-bundle/bundle.yml.
  3. Check git status / .gitignore if the file should have been checked out.

Example fix

# before
specify bundle install ./my-bundle   # contains bundle.yaml

# after
specify bundle install ./my-bundle/bundle.yaml
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

candidate = Path(arg).expanduser()
if candidate.is_dir() and not (candidate / "bundle.yml").exists():
    raise SystemExit(f"{candidate} lacks bundle.yml; pass the manifest path or fix naming")

Type guard

def is_bundle_dir(path: Path) -> bool:
    return path.is_dir() and (path / "bundle.yml").is_file()

Try / catch

try:
    manifest = _local_manifest_source(arg)
except BundlerError as exc:
    if "No bundle.yml found in" in str(exc):
        # pass <dir>/bundle.yml or an unambiguous manifest path
        ...

Prevention

When it happens

Trigger: specify bundle install ./my-bundle where ./my-bundle exists but the manifest is named bundle.yaml/manifest.yml, lives deeper, or is missing entirely.

Common situations: Renamed bundle.yml to bundle.yaml; cloned a repo whose bundle.yml is gitignored; pointed at the workspace root instead of the bundle's folder.

Related errors


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