bevyengine/bevy · error · PrepareAssetError
Failed to build bind group: {0}
Error message
Failed to build bind group: {0} What it means
`PrepareAssetError::AsBindGroupError(AsBindGroupError)` is the hard-failure variant of render-asset preparation: building the bind group for an `AsBindGroup` material failed. The prepare system logs it via `error!` ("{type} Bind group construction failed: {e}") and the asset is skipped for that frame, so the material does not render until re-prepared.
Source
Thrown at crates/bevy_render/src/erased_render_asset.rs:24
use bevy_asset::RenderAssetUsages;
use bevy_asset::{Asset, AssetEvent, AssetId, Assets, UntypedAssetId};
use bevy_ecs::{
prelude::{Commands, IntoScheduleConfigs, Local, MessageReader, ResMut, Resource},
schedule::{ScheduleConfigs, SystemSet},
system::{ScheduleSystem, StaticSystemParam, SystemParam, SystemParamItem, SystemState},
world::{FromWorld, Mut},
};
use bevy_log::{debug, error};
use bevy_platform::collections::{HashMap, HashSet};
use bevy_render::render_asset::RenderAssetBytesPerFrameLimiter;
use core::marker::PhantomData;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum PrepareAssetError<E: Send + Sync + 'static> {
#[error("Failed to prepare asset")]
RetryNextUpdate(E),
#[error("Failed to build bind group: {0}")]
AsBindGroupError(AsBindGroupError),
}
/// The system set during which we extract modified assets to the render world.
#[derive(SystemSet, Clone, PartialEq, Eq, Debug, Hash)]
pub struct AssetExtractionSystems;
/// Describes how an asset gets extracted and prepared for rendering.
///
/// In the [`ExtractSchedule`] step the [`ErasedRenderAsset::SourceAsset`] is transferred
/// from the "main world" into the "render world".
///
/// After that in the [`RenderSystems::PrepareAssets`] step the extracted asset
/// is transformed into its GPU-representation of type [`ErasedRenderAsset`].
pub trait ErasedRenderAsset: Send + Sync + 'static {
/// The representation of the asset in the "main world".
type SourceAsset: Asset + Clone;
/// The target representation of the asset in the "render world".View on GitHub (pinned to 396ca72708)
Solutions
- Read the nested AsBindGroupError in the log line — it names the exact binding and mismatch
- Make the `#[texture(dimension = ...)]` attributes match the actual textures you assign at runtime
- Match sampler filtering to texture filterability (depth/unfilterable textures need non-filtering samplers) and check required device features
Example fix
// before #[texture(0, dimension = "2D")] #[sampler(1)] env_map: Option<Handle<Image>>, // actually assigned a cubemap // after #[texture(0, dimension = "Cubemap")] #[sampler(1)] env_map: Option<Handle<Image>>,
Defensive patterns
Strategy: try-catch
Validate before calling
// before relying on a material, dry-run its bind group inputs let layout_ok = device.limits().max_bind_groups >= expected_bindings; assert!(layout_ok, "device cannot host this material layout");
Try / catch
// when implementing or wrapping as_bind_group for custom materials
match material.as_bind_group(&layout, render_device, images) {
Ok(bind_group) => { /* use */ }
Err(AsBindGroupError::RetryNextUpdate) => { /* wait for next frame */ }
Err(e) => error!("material bind group failed: {e:?}"),
} Prevention
- Keep texture dimension attributes in sync with the textures you assign
- Use non-filtering samplers for depth/unfilterable formats
- Act on the first 'Bind group construction failed' log; later frames repeat the same failure
When it happens
Trigger: A material's `as_bind_group` errors during preparation: texture view/sample type not matching the declared `#[texture]` attributes (wrong dimension, non-filterable texture with a filtering sampler), or a binding not buildable on the current device.
Common situations: Declaring `dimension = "2D"` but assigning a cubemap/3D texture; using a filtering sampler on depth/unfilterable formats; bindless-required bindings on hardware without bindless support.
Related errors
- RenderPipelineDescriptor has no FragmentState configured
- sampler attribute must have matching texture attribute
- Please use a more specific shader stage: https://github.com/
- RetryNextUpdate
- CreateBindGroupDirectly
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/4f19df533e5b83a4.
Report an issue: GitHub.