zed-industries/zed · error

Unexpected heading level: {level}

Error message

Unexpected heading level: {level}

What it means

Edit-prediction example specs are parsed with pulldown-cmark into a structured Section state machine; heading End events for H3/H4 are consumed as section boundaries, and any other heading level reaching the catch-all `Event::End(TagEnd::Heading(level))` arm aborts parsing of the whole spec (example_spec.rs:349).

Source

Thrown at crates/edit_prediction/src/example_spec.rs:349

                        Section::EditHistory
                    } else if title.eq_ignore_ascii_case(CURSOR_POSITION_HEADING) {
                        Section::CursorPosition
                    } else if title.eq_ignore_ascii_case(EXPECTED_PATCH_HEADING) {
                        Section::ExpectedPatch
                    } else if title.eq_ignore_ascii_case(REJECTED_PATCH_HEADING) {
                        Section::RejectedPatch
                    } else {
                        Section::Other
                    };
                }
                Event::End(TagEnd::Heading(HeadingLevel::H3)) => {
                    mem::take(&mut text);
                }
                Event::End(TagEnd::Heading(HeadingLevel::H4)) => {
                    mem::take(&mut text);
                }
                Event::End(TagEnd::Heading(level)) => {
                    anyhow::bail!("Unexpected heading level: {level}");
                }
                Event::Start(Tag::CodeBlock(kind)) => {
                    if current_section == Section::EditHistory
                        && text.trim() == ACCEPTED_PREDICTION_MARKER
                    {
                        next_edit_predicted = true;
                    }
                    text.clear();
                    match kind {
                        CodeBlockKind::Fenced(info) => {
                            block_info = info;
                        }
                        CodeBlockKind::Indented => {
                            anyhow::bail!("Unexpected indented codeblock");
                        }
                    };
                }
                Event::Start(_) => {

View on GitHub (pinned to f4178619ac)

Solutions

  1. Change the offending heading to `###` or `####` so the parser recognizes the section boundary.
  2. Re-run the spec parser / test suite locally to confirm the file is accepted.
  3. Add a lint or CI check that rejects unsupported heading levels in example specs.

Example fix

##### Uncommitted diff      // before — H5 hits catch-all arm

#### Uncommitted diff       // after — H4 is consumed as a subsection boundary
Defensive patterns

Strategy: validation

Validate before calling

# reject unsupported heading levels before committing spec files
grep -nE '^#{1,2} |^#{5,6} ' examples/*.md && echo "only ### and #### allowed" || echo OK

Type guard

fn is_supported_heading(level: HeadingLevel) -> bool {
    matches!(level, HeadingLevel::H3 | HeadingLevel::H4)
}

Prevention

When it happens

Trigger: Editing an example-spec markdown file and using `#`, `##`, `#####`, or `######` headings where only `###` (sections) and `####` (subsections) are allowed by the parser.

Common situations: Contributors adding spec sections with the wrong heading depth; markdown auto-formatting or editors promoting/demoting headings; content pasted from other docs with deeper heading trees.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/8e5e365859b8fe05. Report an issue: GitHub.