rust-lang/mdBook · critical
`{}` unexpected Html event: {html}
Error message
`{}` unexpected Html event: {html} What it means
mdbook-html's process_events assumes the dedicated HtmlBlock handling loop (in start_tag) consumes all pulldown-cmark Event::Html events, so receiving a raw Html event here is an invariant violation and panics. The panic includes the source file path to locate the offending chapter. This is an internal contract between the block-handling code and the main event loop.
Source
Thrown at crates/mdbook-html/src/html/tree.rs:335
}
Event::InlineMath(text) => {
let mut span = Element::new("span");
span.insert_attr("class", "math math-inline".into());
self.push(Node::Element(span));
self.append(Node::Text(text.into_tendril()));
self.pop();
}
Event::DisplayMath(text) => {
let mut span = Element::new("span");
span.insert_attr("class", "math math-display".into());
self.push(Node::Element(span));
self.append(Node::Text(text.into_tendril()));
self.pop();
}
Event::Html(html) => {
// The loop in Tag::HtmlBlock should have consumed all
// Html events.
panic!(
"`{}` unexpected Html event: {html}",
self.options.path.display()
);
}
Event::InlineHtml(html) => self.append_html(&html),
Event::FootnoteReference(name) => self.footnote_reference(name),
Event::SoftBreak => {
self.append_text("\n".into());
}
Event::HardBreak => {
self.append(Node::Element(Element::new("br")));
}
Event::Rule => {
self.append(Node::Element(Element::new("hr")));
}
Event::TaskListMarker(checked) => {
let mut input = Element::new("input");
input.insert_attr("disabled", "".into());View on GitHub (pinned to dc21064fc2)
Solutions
- Identify the preprocessor producing raw Html events and change it to emit InlineHtml or wrap HTML in a proper html block.
- Align pulldown-cmark versions between mdbook and any custom preprocessor so event grouping behavior matches.
- Rebuild with preprocessors disabled (mdbook-preprocessor removal from book.toml) to isolate the culprit.
- If no preprocessor is in use, report the parser-version combination as a bug to mdbook.
Example fix
// before (preprocessor emitting raw html events)
events.push(Event::Html(String::from("<div class=\"note\">hi</div>").into()));
// after
events.push(Event::InlineHtml(String::from("<div class=\"note\">hi</div>").into())); Defensive patterns
Strategy: validation
Validate before calling
// preprocessor: never emit bare Event::Html outside html blocks
for ev in &events {
if let Event::Html(_) = ev {
bail!("raw Html event outside HtmlBlock will break mdbook-html rendering");
}
} Try / catch
let out = std::panic::catch_unwind(|| process_events(events, &options));
match out {
Ok(t) => t,
Err(_) => { eprintln!("unexpected Html event: audit preprocessors emitting Event::Html"); std::process::exit(1); }
} Prevention
- Prefer Event::InlineHtml in preprocessors for inline HTML.
- Pin matching pulldown-cmark versions in your preprocessor and mdbook.
- Test preprocessors against a minimal book before wide use.
When it happens
Trigger: A pulldown-cmark Event::Html reaching the main event loop without being wrapped in an HtmlBlock — typically when a custom preprocessor emits raw HTML events, or a parser/version mismatch produces Html events outside html blocks.
Common situations: Using a preprocessor (e.g. one built on pulldown-cmark's programmatic API) that injects Event::Html directly into the stream, mixing incompatible pulldown-cmark versions between mdbook-html and a plugin, or parser changes that stop grouping raw HTML into HtmlBlock events.
Related errors
- internal error: expected empty tag stack. path: `{}` node=
- internal error: expected `{lookup_key:?}` to be in root map
- `{}` unexpected event in html block {event:?}
- invalid key `{name}`
- The BookBuilder should always create a valid book. If you ar
AI-assisted analysis of rust-lang/mdBook@dc21064fc2 (2026-09-01).
Data as JSON: /api/errors/539b7f704bfa60c1.
Report an issue: GitHub.