What Happens with Unknown Section Headings in DESIGN.md: Parser Behavior Explained

Unknown section headings in DESIGN.md are preserved and not treated as errors, allowing designers to include custom sections like ## Iconography without breaking existing tooling.

The DESIGN.md specification defines a structured format for design system documentation, using top-level Markdown headings (## …) to demarcate semantic blocks like Colors and Typography. When working with this format, authors often need to include custom sections that fall outside the core schema, making it critical to understand how the parser handles unknown section headings.

Consumer Behavior for Unknown Content

According to the docs/spec.md file in the google-labs-code/design.md repository, the parser implements a deliberately tolerant approach to section headings. When a consumer—whether the CLI linter, a parser library, or any tool implementing the spec—encounters a heading it does not recognize, it preserves the content rather than throwing an error.

This behavior is explicitly defined in the Consumer Behavior for Unknown Content section of [docs/spec.md](https://github.com/google-labs-code/design.md/blob/main/docs/spec.md) (lines 360-665), which states that unknown section headings should be retained verbatim. The [README.md](https://github.com/google-labs-code/design.md/blob/main/README.md) (lines 164-172) reiterates this rule, ensuring consistent implementation across different consumer tools.

Design Rationale: Extensibility and Forward Compatibility

The decision to preserve unknown section headings rather than reject them serves three architectural purposes:

  • Extensibility – Projects can add custom sections (e.g., "Iconography", "Brand Voice", or "Accessibility Guidelines") without breaking existing linting or parsing tools.
  • Forward compatibility – Future versions of the specification may introduce new standardized sections; older tooling will continue to process files without rejecting newer content.
  • Loose coupling – The specification separates validation (ensuring known sections conform to schema) from preservation (keeping unknown content intact), mirroring the "preserve-unknown-fields" pattern used in protocols like protobuf and JSON Schema.

This tolerance applies specifically to unknown headings. If a file contains duplicate known headings—such as two ## Colors blocks—the parser errors and rejects the file. This distinction ensures that accidental duplication of required sections is caught while allowing intentional extensions.

Practical Validation with the DESIGN.md CLI

The @google/design.md CLI demonstrates this behavior in practice. When linting a file containing an unknown section heading, the tool preserves the content in the output while validating known sections.

Consider a DESIGN.md file that includes a custom ## Iconography section:


# Create a sample DESIGN.md with an unknown heading

cat > example.md <<'EOF'

# My Design System

## Colors

primary: '#ff0000'

## Iconography          # <-- unknown heading

icons:
  home: 'home.svg'
EOF

# Run the linter in JSON format

npx @google/design.md lint --format json example.md

The resulting JSON output includes the unknown section in a preserved array:

{
  "errors": [],
  "warnings": [],
  "preserved": [
    {
      "type": "section",
      "heading": "Iconography",
      "content": "icons:\n  home: 'home.svg'"
    }
  ]
}

No errors are reported for ## Iconography; the parser records it under preserved so downstream tools can maintain the content unchanged.

Duplicate Headings Trigger Errors

To contrast, attempting to lint a file with duplicate known headings produces a validation error:

cat > dup.md <<'EOF'

# My Design System

## Colors

primary: '#ff0000'

## Colors               # Duplicate

secondary: '#00ff00'
EOF

npx @google/design.md lint dup.md

The CLI returns a non-zero exit status with an error message:


✖ Duplicate section heading: Colors (line 7)

Key Implementation Files

The handling of unknown section headings is implemented across several key files in the google-labs-code/design.md repository:

  • docs/spec.md – Defines the official specification for consumer behavior, including the rule to preserve unknown section headings (lines 360-665).
  • README.md – Provides user-facing documentation summarizing how unknown content is processed (lines 164-172).
  • packages/cli/src/linter/* – Contains the linter implementation that enforces the specification rules, including the distinction between unknown and duplicate headings.
  • examples/*/DESIGN.md – Demonstrates practical usage with both standardized and custom sections.

Summary

  • Unknown section headings in DESIGN.md are preserved rather than rejected, appearing in the preserved array of linter output.

  • This behavior supports extensibility and forward compatibility, allowing custom sections without breaking existing tools.

  • Duplicate known headings (e.g., two ## Colors blocks) generate errors, while unknown headings do not.

  • The specification in docs/spec.md explicitly mandates this tolerant parsing approach under Consumer Behavior for Unknown Content.

Frequently Asked Questions

What happens if I use an unknown section heading in DESIGN.md?

The parser preserves the unknown section heading and its content without raising errors. According to the docs/spec.md specification, consumers must retain unknown sections in their output (typically under a preserved field) while continuing to validate known sections. This allows your custom sections to remain intact for future processing or manual review.

Will unknown sections cause the DESIGN.md linter to fail?

No. The @google/design.md linter exits successfully (status 0) when encountering unknown section headings, provided there are no other validation errors such as malformed content in known sections or duplicate headings. The linter includes unknown sections in the JSON output's preserved array, making them visible without treating them as failures.

Can I have multiple custom section headings in one file?

Yes. The specification places no limits on the number of unknown section headings you can include. You can define multiple custom sections—such as ## Iconography, ## Brand Voice, and ## Motion—and the parser will preserve each one independently. These sections are treated as opaque content blocks that pass through validation unchanged.

What is the difference between unknown and duplicate section headings?

Unknown section headings are headings not defined in the core schema (like ## Iconography); these are preserved. Duplicate section headings occur when a known section (like ## Colors) appears more than once in the same file. The parser treats duplicates as errors because they create ambiguity in the design system specification, whereas unknown headings are assumed to be intentional extensions.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →