Skip to content

Fix YAML front matter not parsed when file ends without trailing newline - #4149

Open
JSap0914 wants to merge 1 commit into
mkdocs:masterfrom
JSap0914:fix/yaml-meta-no-trailing-newline
Open

JSap0914 wants to merge 1 commit into
mkdocs:masterfrom
JSap0914:fix/yaml-meta-no-trailing-newline

Conversation

@JSap0914

Copy link
Copy Markdown

Bug

get_data() in mkdocs/utils/meta.py silently drops YAML front matter when the file ends without a trailing newline after the closing delimiter (--- or ...).

Reproducer

from mkdocs.utils.meta import get_data

# File content with no trailing newline after ---
get_data("---\ntitle: My Page\n---")
# Returns: ('---\ntitle: My Page\n---', {})   ← metadata lost
# Expected: ('', {'title': 'My Page'})

Root Cause

YAML_RE ends with a literal \n:

YAML_RE = re.compile(r'^-{3}[ \t]*\n(.*?\n)(?:\.{3}|-{3})[ \t]*\n', ...)

This requires a newline character after the closing ---/.... When the closing delimiter is the last byte in the file, there is no such newline and the regex does not match. The parser then falls through to the MultiMarkdown path, which also does not recognise --- and returns the entire front-matter block as document content with an empty metadata dict.

Fix

Replace the trailing \n with (?:\n|$) so the pattern matches both a newline and end-of-string. This is backward-compatible: existing files with trailing newlines continue to match as before.

-YAML_RE = re.compile(r'^-{3}[ \t]*\n(.*?\n)(?:\.{3}|-{3})[ \t]*\n', re.UNICODE | re.DOTALL)
+YAML_RE = re.compile(r'^-{3}[ \t]*\n(.*?\n)(?:\.{3}|-{3})[ \t]*(?:\n|$)', re.UNICODE | re.DOTALL)

Verification

pytest mkdocs/tests/utils/utils_tests.py -k meta -v
# 8 passed (6 existing + 2 new)

AI-assisted contribution: this fix was identified and implemented with AI assistance.

…newline

The YAML_RE regex required a literal newline character after the closing
delimiter (--- or ...). When a Markdown file has a YAML front matter block
but ends at the closing delimiter with no trailing newline, the regex failed
to match. As a result, get_data() returned an empty metadata dict and the
entire front matter block (including the --- markers) as document body.

Replace the mandatory trailing \n with (?:\n|$) so the pattern also
matches at end-of-string. This is a strict superset: files with a trailing
newline continue to match as before.

Fixes: YAML_RE in mkdocs/utils/meta.py
Copilot AI review requested due to automatic review settings June 17, 2026 07:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants