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

generation collision or corruption at {destination}

Error message

generation collision or corruption at {destination}

What it means

The existing manifest.json parsed successfully but its content differs from the freshly computed manifest. Because the destination path is derived from a hash of all inputs (source hashes, resolved config values, renderer SHA-256), a content mismatch means two different input sets claimed the same location -- external tampering, a partial renderer upgrade, or an astronomically unlikely hash collision. The renderer refuses to overwrite.

Source

Thrown at src/scripts/render_skill.py:277

        if target not in source_names:
            raise RenderError(f"snapshot reference targets undeclared source: {target}")
        return str(destination / target)

    rendered: dict[str, str] = {}
    for name, content in sources.items():
        # Inserted paths and customization prose are never scanned as source tokens.
        rendered[name] = token_pattern.sub(replace, content)
    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:

View on GitHub (pinned to b70486b9bd)

Solutions

  1. If the existing directory was hand-modified, delete it and re-run render.
  2. If caused by a renderer upgrade, remove stale generations and regenerate.
  3. Commit generations to VCS unmodified so divergence is visible in diffs.

Example fix

# before: a mismatched generation blocks re-render
# after
rm -rf _bmad/render/<skill>/<slug>-<hash>
# then re-run the renderer
Defensive patterns

Strategy: try-catch

Try / catch

from render_skill import render, RenderError

try:
    entry = render(project_root, skill_dir)
except RenderError as e:
    if "generation collision or corruption" in str(e):
        # a prior generation diverged -- remove it and regenerate
        ...
    raise

Prevention

When it happens

Trigger: A generation directory exists at the computed hash, but its recorded inputs/outputs differ from the current run -- e.g. files under the generation dir were modified, or the renderer source changed such that identity no longer matches.

Common situations: Manual modification of a generated directory; a renderer upgrade leaving stale generations; symlink/permission tricks altering recorded inputs.

Related errors


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