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
- Change the offending heading to `###` or `####` so the parser recognizes the section boundary.
- Re-run the spec parser / test suite locally to confirm the file is accepted.
- 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
- Document the H3/H4-only convention at the top of each spec directory.
- Run the spec parser as a CI check on every spec change.
- Disable editor auto-formatting that can shift heading levels in spec files.
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
- Unexpected indented codeblock
- cursor position marker line must contain '^' or '<' before [
- Failed to parse example on {}:{} {error}
- Missing cursor position codeblock
- No eval-cli binary provided. Either pass binary_path=/path/t
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/8e5e365859b8fe05.
Report an issue: GitHub.