{"record":{"id":"5ea6f86d03bb8674","repo":"squidfunk/mkdocs-material","slug":"expected-string-but-received-title","errorCode":null,"errorMessage":"Expected string, but received: {title}","messagePattern":"Expected string, but received: (.+?)","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"src/plugins/tags/structure/mapping/storage/__init__.py","lineNumber":206,"sourceCode":"    Returns:\n        The link.\n    \"\"\"\n    if not isinstance(data, dict):\n        raise ValidationError(\n            f\"Expected dictionary, but received: {data}\"\n        )\n\n    # Ensure item has URL\n    url = data.get(\"url\")\n    if not isinstance(url, str):\n        raise ValidationError(\n            f\"Expected string, but received: {url}\"\n        )\n\n    # Ensure item has title\n    title = data.get(\"title\")\n    if not isinstance(title, str):\n        raise ValidationError(\n            f\"Expected string, but received: {title}\"\n        )\n\n    # Create and return item\n    return Link(title, url)\n","sourceCodeStart":188,"sourceCodeEnd":212,"githubUrl":"https://github.com/squidfunk/mkdocs-material/blob/e2136532f40aed98af1f6497c0cc6a3cff9f759b/src/plugins/tags/structure/mapping/storage/__init__.py#L188-L212","documentation":"_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.","triggerScenarios":"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\"}).","commonSituations":"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.","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"],"exampleFix":"// before\n{\"item\": {\"url\": \"setup/\", \"title\": null}, \"tags\": [\"setup\"]}\n// after\n{\"item\": {\"url\": \"setup/\", \"title\": \"Setup\"}, \"tags\": [\"setup\"]}","handlingStrategy":"validation","validationCode":"import json\nwith open(path) as f:\n    data = json.load(f)\nfor m in data.get(\"mappings\", []):\n    title = (m.get(\"item\") or {}).get(\"title\")\n    if not isinstance(title, str):\n        raise ValueError(f\"entry {m!r}: item.title must be a string\")","typeGuard":"def item_has_title(entry: dict) -> bool:\n    item = entry.get(\"item\")\n    return isinstance(item, dict) and isinstance(item.get(\"title\"), str)","tryCatchPattern":"from mkdocs.config.base import ValidationError\ntry:\n    mappings = list(storage.load(path))\nexcept ValidationError as err:\n    log.error(\"Item missing/invalid title in %s: %s\", path, err)\n    mappings = []","preventionTips":["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"],"tags":["python","mkdocs","json-deserialization","validation"],"backgroundTag":"json-schema-mismatch","analyzedSha":"e2136532f40aed98af1f6497c0cc6a3cff9f759b","analyzedAt":"2026-08-29T11:20:04.299Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}