squidfunk/mkdocs-material · error · ValidationError

Expected list, but received: {mappings}

Error message

Expected list, but received: {mappings}

What it means

After confirming the root of a serialized mappings file is a dictionary, `Storage.load` fetches the `mappings` key and requires it to be a JSON list to iterate and deserialize each entry. A missing or non-list `mappings` value raises this ValidationError.

Source

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

        Arguments:
            path: The file path.

        Yields:
            The current mapping.
        """
        with open(path, "r", encoding = "utf-8") as f:
            data = json.load(f)

            # Ensure root dictionary
            if not isinstance(data, dict):
                raise ValidationError(
                    f"Expected dictionary, but received: {data}"
                )

            # Ensure mappings are iterable
            mappings = data.get("mappings")
            if not isinstance(mappings, list):
                raise ValidationError(
                    f"Expected list, but received: {mappings}"
                )

            # Create and yield mappings
            for mapping in mappings:
                yield _mapping_from_json(mapping)

# -----------------------------------------------------------------------------
# Functions
# -----------------------------------------------------------------------------

def _mapping_to_json(mapping: Mapping) -> dict:
    """
    Return a serializable representation of a mapping.

    Arguments:
        mapping: The mapping.

View on GitHub (pinned to e2136532f4)

Solutions

  1. Ensure the file contains a top-level `"mappings": [ ... ]` array of mapping objects.
  2. Regenerate the file using the export tooling of the installed mkdocs-material version.
  3. If migrating from an older format, convert the keyed dict of mappings into an array.
  4. Guard the load site by checking `isinstance(data.get('mappings'), list)` first.

Example fix

// before
{
  "mappings": {"tag-a": [...]}
}

// after
{
  "mappings": [
    {"tags": ["tag-a"], ...}
  ]
}
Defensive patterns

Strategy: type-guard

Validate before calling

import json
with open(path) as f:
    data = json.load(f)
assert isinstance(data, dict) and isinstance(data.get('mappings'), list), f"{path}: expected {'mappings': [...] }"

Type guard

def has_valid_mappings(data):
    m = data.get('mappings') if isinstance(data, dict) else None
    return isinstance(m, list)

Try / catch

try:
    yield from storage.load(path)
except ValidationError as e:
    log.error(f"Bad 'mappings' key in {path}: {e}")
    raise SystemExit(1)

Prevention

When it happens

Trigger: Mapping JSON where `mappings` is absent, an object/dict, a string, or null; hand-crafted cache files; format drift from a different plugin version that stored mappings as a dict keyed by tag.

Common situations: Editing exports and replacing the array with an object; mixing files produced by incompatible mkdocs-material versions; partial writes/truncation corrupting the structure.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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