yewstack/yew · error · syn::Error
`break`, `continue`, and `return` in a match arm cannot be f
Error message
`break`, `continue`, and `return` in a match arm cannot be followed by HTML as their value. Wrap the arm body in braces, e.g. `_ => { return ::yew::html!(<span/>) }`. What it means
Inside a `html!` match arm, `break`/`continue`/`return` are parsed as divergent control-flow trees; if HTML tokens follow such an expression in the same arm, the macro cannot give the arm a value and rejects it (html_match.rs:145-157). The help text shows the fix: wrap the arm body in braces and make the HTML an explicit `html!` call.
Source
Thrown at packages/yew-macro/src/html_tree/html_match.rs:153
}
}
let comma: Option<Token![,]> = input.parse()?;
// An unbraced `break`/`continue`/`return` body followed by more tokens
// past the optional comma is almost always an attempt to give the
// keyword an HTML value, which Rust does not accept as an expression.
// Without this check the next-arm parser runs on the trailing `<...>`
// and fails inside `Pat::parse` with a misleading "expected `>`".
if comma.is_none() && !input.is_empty() {
if let HtmlMatchArmBody::Unbraced { tree, .. } = &body {
if matches!(
&**tree,
super::HtmlTree::Break(_)
| super::HtmlTree::Continue(_)
| super::HtmlTree::Return(_)
) {
return Err(syn::Error::new(
input.span(),
"`break`, `continue`, and `return` in a match arm cannot be followed by \
HTML as their value. Wrap the arm body in braces, e.g. `_ => { return \
::yew::html!(<span/>) }`.",
));
}
}
}
Ok(HtmlMatchArm {
pat,
guard,
fat_arrow_token,
body,
comma,
})
}
}View on GitHub (pinned to 0e4a05472f)
Solutions
- Wrap the arm body in braces with an explicit macro call, exactly as the help shows: `_ => { return ::yew::html!(<span/>) }`
- Move the early exit out of `html!`: bail or compute in plain Rust before invoking the macro
- Give the arm a real value (`None => <em/>`) instead of diverging mid-template
Example fix
// before
html! {
match item {
Some(i) => <li>{ i }</li>,
None => return empty()
<li/>,
}
}
// after
html! {
match item {
Some(i) => <li>{ i }</li>,
None => { return ::yew::html!(<li/>) },
}
} Defensive patterns
Strategy: validation
Prevention
- Wrap any arm body that starts with `return`/`break`/`continue` in braces with an explicit `html!` call inside
- Hoist early exits out of the template: compute or bail in plain Rust before invoking `html!`
- Give every arm a renderable value; treat divergence as a code smell inside markup
When it happens
Trigger: An arm body like `None => return fallback() <li/>` — a `return`, `break`, or `continue` expression directly followed by more HTML tokens within the same match arm inside `html!`.
Common situations: Early-exit arms while rendering lists or guard clauses ('if none, bail out of the render'), or transplanting plain Rust match code that used `?`/`return` into an `html!` template.
Related errors
- missing expression for `match`
- this `match` expression has a scrutinee, but no body
- `match` expression must have at least one arm
- string literals must not contain more than one class (hint:
- expected a valid closing tag for component note: found openi
AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22).
Data as JSON: /api/errors/80d41d2fddebcba1.
Report an issue: GitHub.