bevyengine/bevy · error · syn::Error

Scene component {} needs to be prefixed by '@'

Error message

Scene component {} needs to be prefixed by '@'

What it means

This is a compile-time error from the bsn! macro's parser (bevy_scene/macros). While parsing a scene entry, the parser resolved a Rust path that refers to a type or enum, but only types preceded by '@' are accepted as scene components in scene position (e.g. inside Children [...] lists). The '@' prefix is how BSN distinguishes a scene component (a type implementing Scene) from a plain component.

Source

Thrown at crates/bevy_scene/macros/src/bsn/parse.rs:259

            BsnScene::Asset(path)
        } else if input.peek(Brace) {
            err_if_cached("Cannot cache scene expressions")?;
            BsnScene::Expression(braced_tokens(input)?)
        } else if input.peek(At) {
            input.parse::<At>()?;
            let sc = input.parse::<BsnType>()?;
            if sc.fields.len() > 0 {
                err_if_cached("Cannot cache Scene Components with props/fields")?;
            }
            BsnScene::SceneComponent(sc)
        } else {
            // PERF: do we really need this fork here?
            let path = input.fork().parse::<Path>()?;
            match PathType::new(&path) {
                PathType::Type | PathType::Enum => {
                    // Scene components are parsed before this if an @ is found.
                    // If this path is hit, that means it wasn't prefixed by @
                    return Err(syn::Error::new(
                        path.span(),
                        format!(
                            "Scene component {} needs to be prefixed by '@'",
                            path_to_string(&path),
                        ),
                    ));
                }
                PathType::Function | PathType::TypeFunction => {
                    let path = input.parse::<Path>()?;
                    let args = input.parse::<BsnFnArgs>()?;
                    if !args.0.is_empty() {
                        err_if_cached("Cannot cache Scene function with arguments")?;
                    }
                    BsnScene::Fn(BsnSceneFn { path, args })
                }
                path_type => {
                    return Err(syn::Error::new(
                        path.span(),

View on GitHub (pinned to 396ca72708)

Solutions

  1. Prefix the scene component with '@': Children [@MySceneComponent]
  2. If the path is meant to be a regular component (not a Scene impl), keep it without '@' but make sure it sits in component position, not in a scene list position
  3. If the path is meant to be a scene-producing function, call it like a function (my_scene_fn()) so it parses as BsnScene::Fn

Example fix

// before
bsn! {
  #Player
  Children [
    MySceneComponent   // a type implementing Scene, missing '@'
    Score(10)
  ]
}

// after
bsn! {
  #Player
  Children [
    @MySceneComponent
    Score(10)
  ]
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Writing a type path in scene/list position inside bsn! without the '@' prefix, e.g. bsn! { Children [MySceneComponent Score(10)] } where MySceneComponent is a type. The parser forks, parses the path, PathType::new reports Type or Enum, and since the '@' branch was not taken earlier, this error is returned.

Common situations: Authors learning BSN syntax who assume scene components are written like normal components; migrating code from an older bevy_scene DSL that had no '@' marker; typos where the '@' was simply forgotten.

Related errors


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