squidfunk/mkdocs-material · error · ValidationError

Expected string, but received: {title}

Error message

Expected string, but received: {title}

What it means

_mapping_item_from_json requires the mapping item's 'title' field to be a string to construct the mkdocs Link. This ValidationError is thrown when 'title' is missing (None) or is another JSON type such as a number, list, or object.

Source

Thrown at src/plugins/tags/structure/mapping/storage/__init__.py:206

    Returns:
        The link.
    """
    if not isinstance(data, dict):
        raise ValidationError(
            f"Expected dictionary, but received: {data}"
        )

    # Ensure item has URL
    url = data.get("url")
    if not isinstance(url, str):
        raise ValidationError(
            f"Expected string, but received: {url}"
        )

    # Ensure item has title
    title = data.get("title")
    if not isinstance(title, str):
        raise ValidationError(
            f"Expected string, but received: {title}"
        )

    # Create and return item
    return Link(title, url)

View on GitHub (pinned to e2136532f4)

Solutions

  1. Add or fix the 'title' field inside each mapping's item so it is a plain string, e.g. "title": "Setup"
  2. Regenerate the mapping file via a fresh build of the source MkDocs project
  3. Find offending entries with jq: .mappings[] | select(.item.title | type != "string")
  4. If titles may legitimately be empty, use "" rather than null, since null fails validation

Example fix

// before
{"item": {"url": "setup/", "title": null}, "tags": ["setup"]}
// after
{"item": {"url": "setup/", "title": "Setup"}, "tags": ["setup"]}
Defensive patterns

Strategy: validation

Validate before calling

import json
with open(path) as f:
    data = json.load(f)
for m in data.get("mappings", []):
    title = (m.get("item") or {}).get("title")
    if not isinstance(title, str):
        raise ValueError(f"entry {m!r}: item.title must be a string")

Type guard

def item_has_title(entry: dict) -> bool:
    item = entry.get("item")
    return isinstance(item, dict) and isinstance(item.get("title"), str)

Try / catch

from mkdocs.config.base import ValidationError
try:
    mappings = list(storage.load(path))
except ValidationError as err:
    log.error("Item missing/invalid title in %s: %s", path, err)
    mappings = []

Prevention

When it happens

Trigger: MappingStorage.load(path) reads a mapping entry where data['item']['title'] is absent, null, or a non-string value (e.g. 42, ["Title"], {"en": "Title"}).

Common situations: Hand-edited or tool-generated mapping files that omit title; i18n tooling replacing title with a per-language object; titles stripped by a JSON transform script.

Related errors


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