Skip to content

AddFrontmatter silently drops the new properties when a document opens with a --- rule that never closes #157

Description

@matt-edmondson

What's wrong

HasFrontmatter (Frontmatter/Frontmatter.cs ~L150-160) returns true as soon as the first line is a delimiter — it never checks for a closing delimiter. The private TrySplitFrontmatterBlocks does require a closed block, so the two disagree about whether a document has frontmatter.

AddFrontmatter (~L185-196) trusts HasFrontmatter, then takes the "present but unreadable, leave it alone" branch because TrySplitFrontmatterBlocks fails, and returns the input unchanged.

Failure scenario (reproduced with an MSTest probe on current main)

A perfectly ordinary markdown document that opens with a thematic break:

string doc = "---\n\n# Heading\n\nText\n";

Frontmatter.HasFrontmatter(doc);                        // true
Frontmatter.ExtractFrontmatter(doc);                    // null
Frontmatter.AddFrontmatter(doc, new() { ["title"] = "T" }); // returns doc unchanged — title silently lost

No exception, no indication of failure: the caller asked for frontmatter to be added and gets the original document back. Any tool that stamps metadata onto markdown files (the main use case) silently skips such files.

Suggested fix

Make HasFrontmatter return true only when a closed frontmatter block exists — e.g. delegate to TrySplitFrontmatterBlocks (keeping the current BOM/trailing-whitespace first-line logic as a private helper that it uses). AddFrontmatter then prepends a header as it does for any document without frontmatter. RemoveFrontmatter/ExtractBody already fall back to the whole input, so they're unaffected.

Acceptance criteria

  • HasFrontmatter("---\n\n# Heading\n") is false.
  • AddFrontmatter("---\n\n# Heading\n\nText\n", {title: T}) returns a document with a title: T header followed by the original content (including its opening --- rule).
  • Existing tests for BOM / trailing-whitespace opening delimiters still pass.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingreadyFully specified; implement as written

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions