squidfunk/mkdocs-material · error · PluginError
Error reading metadata of post '{path}' in '{docs}': Expecte
Error message
Error reading metadata of post '{path}' in '{docs}':
Expected metadata to be defined but found nothing What it means
Blog posts must start with a YAML metadata block delimited by `---` lines, parsed via YAML_RE. If the regex finds no metadata block at the top of the markdown file, the Post constructor raises this PluginError because the plugin expects required metadata (title, date, etc.) to be defined.
Source
Thrown at src/plugins/blog/structure/__init__.py:73
# Resolve path relative to docs directory
docs = os.path.relpath(config.docs_dir)
path = os.path.relpath(file.abs_src_path, docs)
# Read contents and metadata immediately
with open(file.abs_src_path, encoding = "utf-8-sig") as f:
self.markdown = f.read()
# Sadly, MkDocs swallows any exceptions that occur during parsing.
# Since we want to provide the best possible user experience, we
# need to catch errors early and display them nicely. We decided to
# drop support for MkDocs' MultiMarkdown syntax, because it is not
# correctly implemented anyway. When using MultiMarkdown syntax, all
# date formats are returned as strings and list are not properly
# supported. Thus, we just use the relevants parts of `get_data`.
match: Match = YAML_RE.match(self.markdown)
if not match:
raise PluginError(
f"Error reading metadata of post '{path}' in '{docs}':\n"
f"Expected metadata to be defined but found nothing"
)
# Extract metadata and parse as YAML
try:
self.meta = yaml.load(match.group(1), SafeLoader) or {}
self.markdown = self.markdown[match.end():].lstrip("\n")
# The post's metadata could not be parsed because of a syntax error,
# which we display to the author with a nice error message
except Exception as e:
raise PluginError(
f"Error reading metadata of post '{path}' in '{docs}':\n"
f"{e}"
)
# Hack: if the meta plugin is registered, we need to move the callView on GitHub (pinned to e2136532f4)
Solutions
- Add a proper metadata block at the very top of the post: first line `---`, metadata, then a closing `---`
- Remove or move the file out of the configured `posts_dir` if it is not a blog post
- Check for a BOM or stray characters before the opening `---` and remove them
Example fix
# before (posts/my-post.md) # My Post Some text // after --- title: My Post date: 2024-01-15 --- # My Post Some text
Defensive patterns
Strategy: validation
Validate before calling
import pathlib
def has_front_matter(p):
text = p.read_text(encoding='utf-8-sig')
return text.startswith('---') and '\n---' in text[3:]
missing = [p for p in pathlib.Path('docs/posts').rglob('*.md') if not has_front_matter(p)]
assert not missing, f"Posts missing front matter: {missing}"
Type guard
def has_valid_front_matter(text):
stripped = text.lstrip('\ufeff')
return stripped.startswith('---') and stripped.count('---') >= 2
Try / catch
try:
mkdocs.commands.build(config)
except PluginError as e:
if "Expected metadata to be defined" in str(e):
log.error(f"Add a '--- ... ---' metadata block to: {e}")
raise
Prevention
- Always start blog posts with a `---` metadata block including at least title and date
- Never put non-post markdown files into the configured posts_dir
- Save files as UTF-8 without BOM
- Use an editor snippet/template for new posts to guarantee the front-matter
When it happens
Trigger: A file inside the blog `posts_dir` has no leading `--- ... ---` metadata block, or the block is malformed such that YAML_RE does not match (e.g. missing opening/closing `---`, BOM, or leading blank/comment lines before the block).
Common situations: Adding a plain markdown note into the posts directory; deleting the metadata while editing; an editor stripping the front-matter; a file with Windows BOM or different fence characters.
Related errors
- Error reading metadata of post '{path}' in '{docs}': {e}
- Error reading authors file '{path}' in '{docs}': {e}
- Error reading metadata '{k}' of post '{path}' in '{docs}': {
- Expected iterable tags, but received: {value}
- Expected a {str}, {int}, {float} or {bool} but received: {ty
AI-assisted analysis of squidfunk/mkdocs-material@e2136532f4 (2026-08-29).
Data as JSON: /api/errors/64d877fdbd364057.
Report an issue: GitHub.