bevyengine/bevy · error

Not supported in this position, please use one of the follow

Error message

Not supported in this position, please use one of the following:
- path to function
- call to function yielding closure

What it means

Compile-time error from HookAttributeKind::from_expr: the expression given to a component hook attribute (e.g. on_insert/on_remove) is neither a plain path to a hook function nor a call expression that yields a closure; other expression forms (literals, blocks, method chains) are not supported in that position.

Source

Thrown at crates/bevy_ecs/macro_logic/src/component.rs:571

impl HookAttributeKind {
    fn parse(
        input: syn::parse::ParseStream,
        default_hook_path: impl FnOnce() -> ExprPath,
    ) -> Result<Self> {
        if input.peek(Token![=]) {
            input.parse::<Token![=]>()?;
            input.parse::<Expr>().and_then(Self::from_expr)
        } else {
            Ok(Self::Path(default_hook_path()))
        }
    }

    fn from_expr(value: Expr) -> Result<Self> {
        match value {
            Expr::Path(path) => Ok(HookAttributeKind::Path(path)),
            Expr::Call(call) => Ok(HookAttributeKind::Call(call)),
            // throw meaningful error on all other expressions
            _ => Err(syn::Error::new(
                value.span(),
                [
                    "Not supported in this position, please use one of the following:",
                    "- path to function",
                    "- call to function yielding closure",
                ]
                .join("\n"),
            )),
        }
    }

    fn to_token_stream(&self, bevy_ecs_path: &Path) -> TokenStream {
        match self {
            HookAttributeKind::Path(path) => path.to_token_stream(),
            HookAttributeKind::Call(call) => {
                quote!({
                    fn _internal_hook(world: #bevy_ecs_path::world::DeferredWorld, ctx: #bevy_ecs_path::lifecycle::HookContext) {
                        (#call)(world, ctx)

View on GitHub (pinned to 396ca72708)

Solutions

  1. Pass a path to a function: #[component(on_insert = my_hook)]
  2. Use a call yielding a closure: #[component(on_insert = my_hook_factory())]
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/bevy_ecs/macro_logic/src/component.rs:571 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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