bevyengine/bevy · error · syn::Error

Expected a Template type path

Error message

Expected a Template type path

What it means

Inside `#[derive(FromTemplate)]`, a field annotated `#[template(...)]` must contain either the ident `built_in` (use the built-in template machinery) or a valid type path naming a manual template type. The parser at template.rs:366 first tries an ident; if it is not `built_in` it tries `syn::Path`; if both fail it emits this syn::Error.

Source

Thrown at crates/bevy_ecs/macros/src/template.rs:366

        let is_pub = matches!(field.vis, syn::Visibility::Public(_));
        let field_maybe_pub = if is_pub { quote!(pub) } else { quote!() };
        let ident = &field.ident;
        let ty = &field.ty;
        let index = Index::from(index);
        let mut template_type = TemplateType::FromTemplate;
        for attr in &field.attrs {
            if attr.path().is_ident(TEMPLATE_ATTRIBUTE) {
                attr.parse_args_with(|stream: ParseStream| {
                    let forked = stream.fork();
                    let ident = forked.parse::<Ident>()?;
                    if ident == BUILT_IN_ATTRIBUTE {
                        stream.parse::<Ident>()?;
                        template_type = TemplateType::BuiltIn;
                    } else {
                        if let Ok(path) = stream.parse::<Path>() {
                            template_type = TemplateType::Manual(path);
                        } else {
                            return Err(syn::Error::new(
                                attr.span(),
                                "Expected a Template type path",
                            ));
                        }
                    }
                    Ok(())
                })?;
            }
        }

        let template_type = match template_type {
            TemplateType::FromTemplate => {
                quote!(<#ty as #bevy_ecs::template::FromTemplate>::Template)
            }
            TemplateType::BuiltIn => {
                quote!(<#ty as #bevy_ecs::template::BuiltInTemplate>::Template)
            }
            TemplateType::Manual(path) => quote! {#path},

View on GitHub (pinned to 396ca72708)

Solutions

  1. Use a real type path: `#[template(my_templates::ItemTemplate)]`
  2. Use the built-in form: `#[template(built_in)]`
  3. Remove the `#[template]` attribute entirely so the field falls back to `TemplateType::FromTemplate`
  4. Check the exact attribute spelling expected by your bevy_ecs version (TEMPLATE_ATTRIBUTE is `template`)

Example fix

// before
#[derive(FromTemplate)]
struct Enemy {
    #[template(0)]
    loot: Item,
}

// after
#[derive(FromTemplate)]
struct Enemy {
    #[template(built_in)]
    loot: Item,
}
// or: #[template(templates::ItemTemplate)] loot: Item,
Defensive patterns

Strategy: validation

Validate before calling

cargo check --workspace # syn::Error from the attribute is reported with the exact span

Prevention

When it happens

Trigger: `#[template(0)]`, `#[template("Foo")]`, `#[template(true)]`, `#[template()]` (empty parens), or any attribute payload that is neither the `built_in` ident nor a parseable path like `my_mod::MyTemplate`. Note the payload must be a path, not a generic instantiation with brackets in some malformed form.

Common situations: Typos when copying the attribute from examples; assuming the attribute takes a literal or expression; version drift where the attribute grammar changed; leftover `#[template(...)]` from an abandoned experiment.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/b6f9c3120ce0f947. Report an issue: GitHub.