bmad-code-org/BMAD-METHOD · error · RenderError

generation contains unexpected or missing files: {destinatio

Error message

generation contains unexpected or missing files: {destination}

What it means

The set of files actually on disk under the destination must equal manifest["outputs"] plus manifest.json. Extra files (added manually) or missing ones (deleted) both trip this integrity check, because the snapshot must be exactly its declared file set.

Source

Thrown at src/scripts/render_skill.py:285

    return rendered


def _verify_existing(destination: Path, manifest: dict[str, Any]) -> None:
    manifest_path = destination / "manifest.json"
    try:
        existing = json.loads(manifest_path.read_text(encoding="utf-8"))
    except (OSError, UnicodeError, json.JSONDecodeError) as error:
        raise RenderError(f"corrupt existing generation {destination}: {error}") from error
    if existing != manifest:
        raise RenderError(f"generation collision or corruption at {destination}")
    expected_files = set(manifest["outputs"]) | {"manifest.json"}
    actual_files = {
        path.relative_to(destination).as_posix()
        for path in destination.rglob("*")
        if path.is_file()
    }
    if actual_files != expected_files:
        raise RenderError(f"generation contains unexpected or missing files: {destination}")
    for name, expected_hash in manifest["outputs"].items():
        try:
            actual_hash = _hash_bytes((destination / name).read_bytes())
        except OSError as error:
            raise RenderError(f"failed to verify {destination / name}: {error}") from error
        if actual_hash != expected_hash:
            raise RenderError(f"generation output hash mismatch: {destination / name}")


def _publish(destination: Path, outputs: dict[str, bytes], manifest: dict[str, Any]) -> None:
    destination.parent.mkdir(parents=True, exist_ok=True)
    if destination.exists():
        _verify_existing(destination, manifest)
        return
    staging = Path(tempfile.mkdtemp(prefix=".staging-", dir=destination.parent))
    try:
        for name, content in outputs.items():
            path = staging / name

View on GitHub (pinned to b70486b9bd)

Solutions

  1. Remove stray files (e.g. .DS_Store, *.bak, *.swp) from the generation directory.
  2. Restore any deleted output, or delete the whole directory and regenerate.
  3. Add the generation tree to .gitignore or commit it untouched.

Example fix

# before: a stray .DS_Store sits inside the generation dir
# after
find _bmad/render -name '.DS_Store' -delete
# or fully regenerate
rm -rf _bmad/render/<skill>/<slug>-<hash>
Defensive patterns

Strategy: validation

Validate before calling

import json
from pathlib import Path

def validate_file_set(dest: Path) -> None:
    manifest = json.loads((dest / "manifest.json").read_text(encoding="utf-8"))
    expected = set(manifest["outputs"]) | {"manifest.json"}
    actual = {p.relative_to(dest).as_posix() for p in dest.rglob("*") if p.is_file()}
    if actual != expected:
        raise SystemExit(f"file set mismatch: extra={actual-expected} missing={expected-actual}")

Prevention

When it happens

Trigger: Someone added a stray file into the generation directory, or deleted one of the recorded outputs, so actual_files != expected_files.

Common situations: Manual edits; partial cleanup; backup files (*.bak); editor swap files; OS metadata files (.DS_Store, Thumbs.db).

Related errors


AI-assisted analysis of bmad-code-org/BMAD-METHOD@b70486b9bd (2026-08-13). Data as JSON: /api/errors/570c4490d1bb36b6. Report an issue: GitHub.