Skip to content

MD082 - Headings should have content before the next heading

Aliases: no-empty-sections

Disabled by default. This rule is opt-in: enable it explicitly with extend-enable. There is no markdownlint equivalent; this is a rumdl-specific structure rule.

What this rule does

Flags any heading that is immediately followed by another heading with no rendered content in between. That gap is an empty section: a heading whose body is missing, either a parent heading with nothing under it before its first child, or sibling headings with no content between them.

The following does not count as a section body, so a section containing only these is still empty:

  • blank lines
  • HTML comments (<!-- ... -->)
  • reference-link definitions ([ref]: url)
  • lone thematic breaks (---, ***, ___)

Everything else that renders counts as content: paragraphs, lists, code blocks, tables, blockquotes, and raw HTML such as <div>.

A {#id} attribute list on the line immediately after a heading is its anchor and is treated as part of the heading, not as the section body. An attribute list elsewhere (for example, separated from the heading by a blank line) renders as ordinary text and counts as content.

Only a heading immediately followed by another heading is flagged. A trailing heading at the end of the document with no body is not flagged.

Why this matters

A sub heading directly under a parent heading with nothing in between usually means the document needs restructuring. A heading with no content can often be refactored away, and an empty section between two headings is rarely intentional in finished documentation.

Configuration

Option Type Default Description
level integer 1 Minimum heading level (1-6) that must have content before the next heading. With 1, every heading is checked, including # Title straight into ## Section. Set 2 to exempt H1 while still requiring content under H2 and deeper.
allow-parent-headings boolean false Accept a heading whose next heading is deeper, taking the subsections as the parent's content. Sibling or shallower headings with nothing between them are still flagged.
[MD082]
# Check every heading (1) or exempt H1 and check H2+ (2).
level = 1

# Treat subsections as a parent heading's content.
allow-parent-headings = false

Parent headings

level exempts headings by depth, so level = 2 allows # Title straight into ## Section but still flags ## A straight into ### B. When the objection is to the shape rather than the depth, use allow-parent-headings instead: it accepts any heading whose next heading is deeper, at every level.

[MD082]
allow-parent-headings = true
# Project

## Installation

Run the installer.

# Project is accepted because ## Installation opens a subsection of it. Two headings at the same level with nothing in between are still flagged:

# Project

# Reference

The API reference.

Examples

Correct

# Project

A short introduction to the project.

## Installation

Run the installer.

Incorrect

# Project

## Installation

Run the installer.

# Project runs straight into ## Installation with no content in between, so the # Project section is empty.

Automatic fixes

None. Fixing would mean inventing a section body, which the rule cannot do safely, so it is diagnostic only.