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

unsupported render token: {token}

Error message

unsupported render token: {token}

What it means

Defensive invariant inside _render_sources.replace. The combined regex is assembled from the known replacement tokens plus the snapshot pattern, so any match should be either a known replacement or a snapshot reference. If a matched token is somehow neither, this fires. Not reachable under correct pattern construction; it indicates a bug in pattern assembly or tampering with the replacements dict.

Source

Thrown at src/scripts/render_skill.py:257

        token: value.replace("{skill-root}", str(destination))
        if token.startswith("{workflow.")
        else value
        for token, value in replacements.items()
    }
    source_names = set(sources)
    patterns = [
        *(re.escape(token) for token in sorted(replacements, key=len, reverse=True)),
        _SNAPSHOT_TOKEN.pattern,
    ]
    token_pattern = re.compile("|".join(patterns))

    def replace(match: re.Match[str]) -> str:
        token = match.group(0)
        if token in replacements:
            return replacements[token]
        snapshot = _SNAPSHOT_TOKEN.fullmatch(token)
        if snapshot is None:
            raise RenderError(f"unsupported render token: {token}")
        target = snapshot.group(1)
        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

View on GitHub (pinned to b70486b9bd)

Solutions

  1. Do not modify or monkey-patch renderer internals.
  2. Upgrade to a released version of the renderer.
  3. Report a bug including the exact offending token string from the message.
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 "unsupported render token" in str(e):
        # internal invariant -- report and upgrade/file a bug
        ...
    raise

Prevention

When it happens

Trigger: Effectively unreachable through normal use. Could only surface if the replacements dict is mutated to non-string keys/values between pattern build and substitution, or via a regex construction edge case.

Common situations: Internal regression after monkey-patching renderer internals; corrupted in-memory state.

Related errors


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