leptos-rs/leptos · error

element needs to have a name

Error message

element needs to have a name

What it means

ident_from_tag_name in leptos_macro's view! macro derives the element identifier from the tag's AST path. It unwraps the last path segment; if the path has zero segments (an empty path in the tag-name position), the expect panics with 'element needs to have a name'. This is a compile-time macro panic, so it aborts the rustc build rather than failing at runtime.

Source

Thrown at leptos_macro/src/view/mod.rs:1911

}

fn convert_to_snake_case(name: String) -> String {
    if !is_case(&name, Snake) {
        name.to_case(Snake)
    } else {
        name
    }
}

pub(crate) fn ident_from_tag_name(tag_name: &NodeName) -> Ident {
    match tag_name {
        NodeName::Path(path) => path
            .path
            .segments
            .iter()
            .next_back()
            .map(|segment| segment.ident.clone())
            .expect("element needs to have a name"),
        NodeName::Block(_) => {
            let span = tag_name.span();
            proc_macro_error2::emit_error!(
                span,
                "blocks not allowed in tag-name position"
            );
            Ident::new("", span)
        }
        _ => Ident::new(
            &tag_name.to_string().replace(['-', ':'], "_"),
            tag_name.span(),
        ),
    }
}

pub(crate) fn full_path_from_tag_name(tag_name: &NodeName) -> Option<ExprPath> {
    match tag_name {
        NodeName::Path(path) => Some(path.clone()),

View on GitHub (pinned to 32d20f6c9d)

Solutions

  1. Inspect the view! call reported by rustc and give the element a concrete tag name (e.g. <div>...</div>).
  2. If the tag name comes from a macro-generated token stream, check the generator for empty paths being emitted.
  3. If you intended a dynamic element, use a valid block/tag expression instead of an empty path in tag position.

Example fix

// before
view! { <>{children}</> with an empty tag path }
// after
view! { <div>{children}</div> }
Defensive patterns

Strategy: validation

Validate before calling

fn has_tag_name(tag: &NodeName) -> bool {
    match tag {
        NodeName::Path(p) => !p.path.segments.is_empty(),
        _ => true,
    }
}

Prevention

When it happens

Trigger: Using view! with a tag name that parses to an empty syn::Path (e.g. an empty or malformed tag-name token stream), so path.segments.iter().next_back() returns None.

Common situations: Hand-written or code-generated macro invocations where a variable or bad token stream is spliced into the tag-name position; broken custom derive/proc-macro tooling emitting empty paths; copy-paste corruption in view! markup.

Related errors


AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01). Data as JSON: /api/errors/59cb304a7f2f81e9. Report an issue: GitHub.