squidfunk/mkdocs-material · error · ValidationError

Expected a {str}, {int}, {float} or {bool} but received: {ty

Error message

Expected a {str}, {int}, {float} or {bool} but received: {type(tag)} at index {index}

What it means

TagSet.run_validation iterates the tags value and requires each element to be a str, int, float, or bool, which is then coerced to a Tag string. This ValidationError is raised with the offending Python type and index when an element is another type (dict, list, None, datetime, etc.), because tags must be simple scalar values nameable as strings.

Source

Thrown at src/plugins/tags/structure/tag/options.py:90

            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)
            if invalid:
                raise ValidationError(
                    "Tags not in allow list: " +
                    ",".join([tag.name for tag in invalid])
                )

        # Return set of tags
        return tags

View on GitHub (pinned to e2136532f4)

Solutions

  1. Make every element of the tags list a scalar string: tags: [foo, bar]
  2. Replace nested mappings like - name: foo with the plain tag name - foo
  3. Remove null/empty entries from the list
  4. Quote tags that YAML would otherwise parse as other types (e.g. "2024-01-01" to keep it a string, though date-like strings already parse as strings only if quoted)
  5. Run the page through a YAML linter to spot unintended nesting

Example fix

# before (front matter)
---
tags:
  - name: python
    category: lang
---
# after
---
tags:
  - python
---
Defensive patterns

Strategy: type-guard

Validate before calling

import yaml
def validate_tag_items(fm: dict) -> None:
    for i, tag in enumerate(fm.get("tags") or []):
        if not isinstance(tag, (str, int, float, bool)):
            raise ValueError(f"tags[{i}] must be scalar, got {type(tag).__name__}")
validate_tag_items(yaml.safe_load(front_matter))

Type guard

def is_scalar_tag(tag: object) -> bool:
    return isinstance(tag, (str, int, float, bool))

Try / catch

from mkdocs.config.base import ValidationError
try:
    page_tags = tag_option.run_validation(raw_value)
except ValidationError as err:
    log.error("Non-scalar tag in front matter: %s", err)

Prevention

When it happens

Trigger: A front matter tags list contains nested structures — e.g. tags:\n - name: foo (a dict), tags: [foo, [bar]] (nested list), tags: [foo, null] — or a filter option passes objects instead of scalar tag names.

Common situations: YAML anchors/merge keys producing dicts inside the tags list; authors putting key-value metadata under tags; a front matter serializer emitting dates or None values into the list.

Related errors


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