bevyengine/bevy · error

Please use a more specific shader stage: https://github.com/

Error message

Please use a more specific shader stage: https://github.com/gfx-rs/wgpu/issues/7708

What it means

In an `AsBindGroup` derive, each binding can declare which shader stages may access it via `visibility(...)`. `visibility(all)` is special: on regular builds it expands to `ShaderStages::all()`, but when the expanded code is compiled with the `webgpu` feature it expands to `todo!()` referencing gfx-rs/wgpu#7708, because WebGPU rejects that stage set for bind group layouts. The panic fires at runtime when the bind group layout is first constructed.

Source

Thrown at crates/bevy_render/macros/src/as_bind_group.rs:1387

            fragment: true,
            ..Default::default()
        }
    }

    fn compute() -> Self {
        Self {
            compute: true,
            ..Default::default()
        }
    }
}

impl ShaderStageVisibility {
    fn hygienic_quote(&self, path: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
        match self {
            ShaderStageVisibility::All => quote! {
                if cfg!(feature = "webgpu") {
                    todo!("Please use a more specific shader stage: https://github.com/gfx-rs/wgpu/issues/7708")
                } else {
                    #path::ShaderStages::all()
                }
            },
            ShaderStageVisibility::None => quote! { #path::ShaderStages::NONE },
            ShaderStageVisibility::Flags(flags) => {
                let mut quoted = Vec::new();

                if flags.vertex {
                    quoted.push(quote! { #path::ShaderStages::VERTEX });
                }
                if flags.fragment {
                    quoted.push(quote! { #path::ShaderStages::FRAGMENT });
                }
                if flags.compute {
                    quoted.push(quote! { #path::ShaderStages::COMPUTE });
                }

View on GitHub (pinned to 396ca72708)

Solutions

  1. Replace `visibility(all)` with an explicit combination such as `visibility(vertex, fragment)` or `visibility(vertex, fragment, compute)`
  2. Prefer the narrowest stage set that matches the shader (the derive's default is already `visibility(vertex, fragment)`)
  3. Until wgpu#7708 is resolved, keep `visibility(all)` out of any code path built for WebGPU

Example fix

// before
#[texture(0, visibility(all))]
#[sampler(1)]
albedo: Option<Handle<Image>>,

// after
#[texture(0, visibility(vertex, fragment))]
#[sampler(1)]
albedo: Option<Handle<Image>>,
Defensive patterns

Strategy: validation

Validate before calling

// compile-time audit: find every occurrence in your AsBindGroup types
//   grep -rn "visibility(all)" src/
// replace each with an explicit stage list, e.g. visibility(vertex, fragment)

Prevention

When it happens

Trigger: Any `#[texture]`, `#[sampler]`, `#[uniform]`, `#[storage]` or `#[storage_texture]` attribute with `visibility(all)` on an AsBindGroup type that is built in a WebGPU configuration; the todo!() triggers when the material's bind group layout is created.

Common situations: Enabling bevy's `webgpu` feature for browser builds on materials that worked on native; using `visibility(all)` copied from other code under the assumption that all-stages is the safe default.

Related errors


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