yewstack/yew · error · syn::Error
expected a valid closing tag for component note: found…
Error message
expected a valid closing tag for component
note: found opening tag `{lt}{0}{gt}`
help: try `{lt}/{0}{gt}` What it means
While parsing children of a non-self-closing component in `html!`, Yew watches for `</` and then attempts to parse the closing tag's content as a Rust type on a forked stream (html_component.rs:71-84). If that type parse fails, this error is raised with the opening tag echoed and the exact closing tag suggested in the help text. It is distinct from the 'mismatched closing tags' error, which fires when the closing type parses fine but differs from the opener.
Solutions
- Replace the malformed closing tag with the one shown in the help text: `</Modal>`
- Never use a bare `</>` inside `html!` — a fragment is written as the complete expression `<></>`
- If the tag looks correct, check for stray punctuation or tokens between `</` and `>`
Example fix
// before
html! {
<Modal>
<p>{ "hi" }</p>
</>
}
// after
html! {
<Modal>
<p>{ "hi" }</p>
</Modal>
} Defensive patterns
Strategy: validation
Prevention
- Unlearn the JSX habit: `</>` is never a valid closer inside `html!`; components close with `</Component>` and fragments are `<></>` as a whole expression
- When converting HTML mockups, finish each element's closing tag before moving to the next
- Read the help line in the error — it prints the exact closing tag to use
When it happens
Trigger: Closing a component with a fragment-style empty tag: `html! { <Modal>…</> }`; a closing tag containing non-type tokens such as `</Modal;>`, `</123>`, or `</Modal=>`.
Common situations: Muscle memory from JSX/React where `</>` closes any element, hand-edited or autocompleted tags with stray punctuation, and converting raw HTML mockups into `html!` macros.
Related errors
- `break`, `continue`, and `return` in a match arm cannot be…
- byte-strings can't be converted to HTML text note: remove…
- duplicate key for a node in a
- expected block or `if` after `else`
- `match` expression must have at least one arm
AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22).
Data as JSON: /api/errors/61941841c83d22ff.
Report an issue: GitHub.
Appendix: source
Thrown at packages/yew-macro/src/html_tree/html_component.rs:74
break None;
}
return Err(syn::Error::new_spanned(
open.to_spanned(),
"this opening tag has no corresponding closing tag",
));
}
if trying_to_close() {
fn format_token_stream(ts: impl ToTokens) -> String {
let string = ts.to_token_stream().to_string();
// remove unnecessary spaces
string.replace(' ', "")
}
let fork = input.fork();
let close = TagTokens::parse_end_content(&fork, |i_fork, tag| {
let ty = i_fork.parse().map_err(|e| {
syn::Error::new(
e.span(),
format!(
"expected a valid closing tag for component\nnote: found opening \
tag `{lt}{0}{gt}`\nhelp: try `{lt}/{0}{gt}`",
format_token_stream(&open.ty),
lt = open.tag.lt.to_token_stream(),
gt = open.tag.gt.to_token_stream(),
),
)
})?;
if ty != open.ty && !is_ide_completion() {
let open_ty = &open.ty;
Err(syn::Error::new_spanned(
quote!(#open_ty #ty),
format!(
"mismatched closing tags: expected `{}`, found `{}`",
format_token_stream(open_ty),View on GitHub (pinned to 0e4a05472f)