squidfunk/mkdocs-material · error · RuntimeError

Unknown type: {type}

Error message

Unknown type: {type}

What it means

The flag shortcode in the shortcodes hook renders badges for flag types like experimental, required, customization, metadata, and multiple. If the <!-- md:flag ... --> type word matches none of these, flag() raises RuntimeError("Unknown type: {type}"). It enforces the fixed vocabulary of flag badges.

Source

Thrown at src/overrides/hooks/shortcodes.py:85

    # Find and replace all external asset URLs in current page
    return re.sub(
        r"<!-- md:(\w+)(.*?) -->",
        replace, markdown, flags = re.I | re.M
    )

# -----------------------------------------------------------------------------
# Helper functions
# -----------------------------------------------------------------------------

# Create a flag of a specific type
def flag(args: str, page: Page, files: Files):
    type, *_ = args.split(" ", 1)
    if   type == "experimental":  return _badge_for_experimental(page, files)
    elif type == "required":      return _badge_for_required(page, files)
    elif type == "customization": return _badge_for_customization(page, files)
    elif type == "metadata":      return _badge_for_metadata(page, files)
    elif type == "multiple":      return _badge_for_multiple(page, files)
    raise RuntimeError(f"Unknown type: {type}")

# Create a linkable option
def option(type: str):
    _, *_, name = re.split(r"[.:]", type)
    return f"[`{name}`](#+{type}){{ #+{type} }}\n\n"

# Create a linkable setting - @todo append them to the bottom of the page
def setting(type: str):
    _, *_, name = re.split(r"[.*]", type)
    return f"`{name}` {{ #{type} }}\n\n[{type}]: #{type}\n\n"

# -----------------------------------------------------------------------------

# Resolve path of file relative to given page - the posixpath always includes
# one additional level of `..` which we need to remove
def _resolve_path(path: str, page: Page, files: Files):
    path, anchor, *_ = f"{path}#".split("#")
    path = _resolve(files.get_file_from_path(path), page)

View on GitHub (pinned to e2136532f4)

Solutions

  1. Use one of the supported types: experimental, required, customization, metadata, multiple.
  2. Correct the spelling in the Markdown file.
  3. If you need a new flag, add an elif branch in flag() with a corresponding badge function.

Example fix

<!-- before -->
<!-- md:flag deprecated -->

<!-- after -->
<!-- md:flag experimental -->
Defensive patterns

Strategy: validation

Validate before calling

VALID_FLAGS = {"experimental", "required", "customization", "metadata", "multiple"}
import re
for m in re.finditer(r"<!-- md:flag (\w+)", markdown, re.I | re.M):
    assert m.group(1).lower() in VALID_FLAGS, f"Unknown flag type: {m.group(1)}"

Type guard

def is_valid_flag(type: str) -> bool:
    return type in {"experimental", "required", "customization", "metadata", "multiple"}

Try / catch

try:
    out = on_page_markdown(md, page, config, files)
except RuntimeError as e:
    if str(e).startswith("Unknown type"):
        print("Flag badge must be one of experimental|required|customization|metadata|multiple:", e)
    else:
        raise

Prevention

When it happens

Trigger: Writing <!-- md:flag optional --> or any flag type not in the implemented list; a typo such as <!-- md:flag experimantal -->; calling flag() directly with an unsupported string.

Common situations: Document authors guessing flag names instead of copying from the project's docs conventions; renaming flags in the hook but not updating Markdown; translating docs and translating the flag word too.

Related errors


AI-assisted analysis of squidfunk/mkdocs-material@e2136532f4 (2026-08-29). Data as JSON: /api/errors/352b9eb02d36da87. Report an issue: GitHub.