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
- Add or fix the 'title' field inside each mapping's item so it is a plain string, e.g. "title": "Setup"
- Regenerate the mapping file via a fresh build of the source MkDocs project
- Find offending entries with jq: .mappings[] | select(.item.title | type != "string")
- 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
- Use "" instead of null for untitled items — null fails validation
- Never let i18n tools replace title with a per-language object
- Verify with jq: .mappings[] | select(.item.title | type != "string")
- Prefer regenerating the file from the source build over manual edits
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
- Expected string, but received: {url}
- Error reading filter configuration in '{key}': {e}
- Relative path processor not registered
- Unknown shortcode: {type}
- Unknown type: {type}
AI-assisted analysis of squidfunk/mkdocs-material@e2136532f4 (2026-08-29).
Data as JSON: /api/errors/5ea6f86d03bb8674.
Report an issue: GitHub.