github/spec-kit · error · BundlerError

Could not read bundle.yml inside '{candidate}': {exc}

Error message

Could not read bundle.yml inside '{candidate}': {exc}

What it means

After extracting the raw bundle.yml bytes from a zip, the CLI decodes them explicitly as UTF-8 (mirroring yamlio.load_yaml). A UnicodeError here means the manifest is not UTF-8 — commonly a UTF-16 file with a BOM, which PyYAML's auto-detecting Reader would otherwise silently accept, creating an inconsistency with the directory and file sources that both require UTF-8.

Source

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

                raise BundlerError(
                    f"Artifact '{candidate}' does not contain a bundle.yml."
                ) from exc
            raw = read_zip_member_limited(
                archive,
                "bundle.yml",
                error_type=BundlerError,
                label="bundle manifest",
            )
        # The bounded-zip helpers above keep archive failures inside the
        # BundlerError contract, but the manifest bytes need the same
        # treatment as yamlio.load_yaml: decode as UTF-8 explicitly —
        # feeding PyYAML the byte stream would let its Reader auto-detect
        # a UTF-16 BOM and accept a manifest the directory and bundle.yml
        # sources reject.
        try:
            text = raw.decode("utf-8")
        except UnicodeError as exc:
            raise BundlerError(
                f"Could not read bundle.yml inside '{candidate}': {exc}"
            ) from exc
        try:
            data = _yaml.safe_load(text)
        except _yaml.YAMLError as exc:
            # The sibling directory/bundle.yml branches reach YAML through
            # load_yaml(), which turns a parse failure into a BundlerError. This
            # branch parses inline, so without this it raises a raw YAMLError --
            # neither a ValueError nor an OSError -- which escapes
            # bundle_install()'s `except BundlerError` as a traceback.
            raise BundlerError(
                f"Invalid YAML in bundle.yml inside '{candidate}': {exc}"
            ) from exc
        return BundleManifest.from_dict(data)

    if candidate.name == "bundle.yml" or candidate.suffix in (".yml", ".yaml"):
        return BundleManifest.from_file(candidate)

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Re-encode the manifest to UTF-8 (without BOM): iconv -f UTF-16 -t UTF-8 bundle.yml, then re-zip.
  2. Configure your editor to save YAML as UTF-8.
  3. Fix the packaging pipeline that produced the artifact.

Example fix

# before
Get-Content bundle.yml | Out-File bundle.yml   # PowerShell: UTF-16

# after (UTF-8, no BOM)
iconv -f UTF-16 -t UTF-8 bundle.yml > bundle.utf8.yml && mv bundle.utf8.yml bundle.yml
Defensive patterns

Strategy: validation

Validate before calling

raw = b'...'  # bytes from the zip member
try:
    text = raw.decode("utf-8")
except UnicodeError:
    raise SystemExit("bundle.yml must be UTF-8 (found BOM/UTF-16?)")

Type guard

def is_utf8_manifest(raw: bytes) -> bool:
    try:
        raw.decode("utf-8")
        return True
    except UnicodeError:
        return False

Try / catch

try:
    manifest = _local_manifest_source(Path("bundle.zip"))
except BundlerError as exc:
    if "Could not read bundle.yml inside" in str(exc):
        # re-encode manifest to UTF-8 without BOM and re-zip
        ...

Prevention

When it happens

Trigger: A bundle.yml saved as UTF-16 (e.g. authored in Windows PowerShell redirection or Notepad defaults) and zipped into the artifact; passed to specify bundle install ./bundle.zip.

Common situations: Windows authoring tools writing UTF-16; build scripts converting encodings; manifests with non-ASCII author names saved in the wrong encoding.

Related errors


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