bevyengine/bevy · error · AsBindGroupError
CreateBindGroupDirectly
CreateBindGroupDirectly
Error message
Create the bind group via `as_bind_group()` instead
What it means
AsBindGroupError::CreateBindGroupDirectly is returned by AsBindGroup paths other than as_bind_group() for implementations that must be created through as_bind_group() (bind_group.rs:580 documents this contract). It tells the caller the attempted creation route (e.g. the unprepared/allocator path) is not supported for this type and the bind group must come from as_bind_group().
Source
Thrown at crates/bevy_render/src/render_resource/bind_group.rs:644
fn bind_group_layout_entries(
render_device: &RenderDevice,
force_no_bindless: bool,
) -> Vec<BindGroupLayoutEntry>
where
Self: Sized;
fn bindless_descriptor() -> Option<BindlessDescriptor> {
None
}
}
/// An error that occurs during [`AsBindGroup::as_bind_group`] calls.
#[derive(Debug, Error)]
pub enum AsBindGroupError {
/// The bind group could not be generated. Try again next frame.
#[error("The bind group could not be generated")]
RetryNextUpdate,
#[error("Create the bind group via `as_bind_group()` instead")]
CreateBindGroupDirectly,
#[error("At binding index {0}, the provided image sampler `{1}` does not match the required sampler type(s) `{2}`.")]
InvalidSamplerType(u32, String, String),
}
/// A prepared bind group returned as a result of [`AsBindGroup::as_bind_group`].
pub struct PreparedBindGroup {
pub bindings: BindingResources,
pub bind_group: BindGroup,
}
impl PreparedBindGroup {
pub(crate) fn unprepare(&self) -> BindGroupBuilder {
let mut data_buffer = vec![];
BindGroupBuilder {
binding_resources: UnpreparedBindingResources(
self.bindings
.iter()View on GitHub (pinned to 396ca72708)
Solutions
- Create the group via as_bind_group() as the message says, and use the returned PreparedBindGroup.
- If you own the implementation, only return this variant from paths you do not support and make sure your material plugin uses as_bind_group.
- Prefer the default Material preparation pipeline, which already handles this variant correctly.
Example fix
// before: unsupported creation path let unprepared = material.unprepared_bind_group(layout_id, &layout, render_device)?; // Err(CreateBindGroupDirectly) // after let prepared = material.as_bind_group(layout_id, &layout, render_device, render_queue, &mut param)?; let bind_group = prepared.bind_group;
Defensive patterns
Strategy: fallback
Try / catch
let group = match material.unprepared_bind_group(layout_id, &layout, render_device) {
Ok(unprepared) => build_from(unprepared),
Err(AsBindGroupError::CreateBindGroupDirectly) => {
material.as_bind_group(layout_id, &layout, render_device, render_queue, &mut param)?.bind_group
}
Err(e) => return Err(e.into()),
}; Prevention
- Read the type's AsBindGroup docs/impl before choosing a creation path.
- Prefer the standard material preparation systems over hand-rolled creation.
- When implementing AsBindGroup, document which creation routes you support.
When it happens
Trigger: Calling unprepared_bind_group (or letting the MaterialBindGroupAllocator create the group from unprepared bindings) on a type whose implementation rejects that route and returns CreateBindGroupDirectly.
Common situations: Custom materials that take full control of bind group creation; bindless (descriptor-indexing) materials; migration between Bevy versions where material bind group creation paths changed; hand-rolled material preparation bypassing the default Material systems.
Related errors
- Failed to build bind group: {0}
- RetryNextUpdate
- executable schedule has not been built
- RenderPipelineDescriptor has no FragmentState configured
- Failed to prepare atmosphere bind groups. Light uniform buff
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/b1e444c47a84eaeb.
Report an issue: GitHub.