squidfunk/mkdocs-material · error · ValidationError
Expected iterable tags, but received: {value}
Error message
Expected iterable tags, but received: {value} What it means
TagSet.run_validation validates tag values coming from page front matter (the 'tags' key) or from plugin filters like tags listings. The value must be an iterable collection of tags — but explicitly NOT a plain string, since a string would iterate character-by-character. This mkdocs ValidationError is raised when the value is neither None nor a non-string iterable (e.g. a number, a bool, or a single string).
Source
Thrown at src/plugins/tags/structure/tag/options.py:82
Validate list of tags.
If the value is `None`, an empty set is returned. Otherwise, the value
is expected to be a list of tags, which is converted to a set of tags.
This means that tags are automatically deduplicated. Note that tags are
not expanded here, as the set is intended to be checked exactly.
Arguments:
value: The value to validate.
Returns:
A set of tags.
"""
if value is None:
return set()
# Ensure tags are iterable
if not isinstance(value, Iterable) or isinstance(value, str):
raise ValidationError(
f"Expected iterable tags, but received: {value}"
)
# Ensure tags are valid
tags: set[Tag] = set()
for index, tag in enumerate(value):
if not isinstance(tag, (str, int, float, bool)):
raise ValidationError(
f"Expected a {str}, {int}, {float} or {bool} "
f"but received: {type(tag)} at index {index}"
)
# Coerce tag to string and add to set
tags.add(Tag(str(tag)))
# Ensure tags are in allow list, if any
if self.allowed:
invalid = tags.difference(self.allowed)View on GitHub (pinned to e2136532f4)
Solutions
- Wrap the value in a list in front matter: tags: [my-tag] or tags:\n - my-tag
- Check YAML indentation — an incorrectly indented block can parse as a scalar string instead of a list
- If the page has no tags, omit the key or use tags: [] (null is allowed and yields an empty set)
- Validate front matter with mkdocs serve/build and inspect the offending page named in the error context
Example fix
# before (front matter) --- tags: my-tag --- # after --- tags: - my-tag ---
Defensive patterns
Strategy: validation
Validate before calling
import yaml
def validate_tags(fm: dict) -> None:
tags = fm.get("tags")
if tags is None:
return
if isinstance(tags, str) or not hasattr(tags, "__iter__"):
raise ValueError(f"tags must be a list, got: {tags!r}")
validate_tags(yaml.safe_load(front_matter)) Type guard
def is_tag_list(value: object) -> bool:
return value is None or (
isinstance(value, (list, tuple, set))
and not isinstance(value, str)
) Try / catch
from mkdocs.config.base import ValidationError
try:
page_tags = tag_option.run_validation(raw_value)
except ValidationError as err:
log.error("Bad 'tags' front matter on page: %s", err) Prevention
- Always write front matter tags as a YAML list, never a bare string
- Use tags: [single-tag] bracket syntax to avoid indentation mistakes
- Omit the tags key entirely for untagged pages
- Lint front matter YAML in CI before building
- Remember strings iterate per-character, which is why the plugin rejects them
When it happens
Trigger: A page's front matter sets tags: my-tag (a bare string instead of a list); tags: true or tags: 3; or a TagSet filter option receives a scalar instead of a list of tags.
Common situations: YAML front matter typo where the author forgot the list syntax and wrote tags: foo instead of tags: [foo] or tags:\n - foo; copying a single-tag example from docs; a template or script injecting a scalar into front matter.
Related errors
- Error reading metadata of post '{path}' in '{docs}': Expecte
- Error reading metadata of post '{path}' in '{docs}': {e}
- Expected a {str}, {int}, {float} or {bool} but received: {ty
- Error reading filter configuration in '{key}': {e}
- Error reading authors file '{path}' in '{docs}': {e}
AI-assisted analysis of squidfunk/mkdocs-material@e2136532f4 (2026-08-29).
Data as JSON: /api/errors/60503633fb65abed.
Report an issue: GitHub.