bevyengine/bevy · critical
Data ranges have no binding resource
Error message
Data ranges have no binding resource
What it means
UnpreparedBindingResource::get_binding() (bind_group.rs:871) panics on the Data variant because a raw value range corresponds to no binding by itself - it must be packed into a buffer by the MaterialBindGroupAllocator before it can be bound. The panic mirrors the OwnedBindingResource::Data case one level earlier, on the unprepared representation.
Source
Thrown at crates/bevy_render/src/render_resource/bind_group.rs:871
UnpreparedBindingResource::Sampler(_, sampler) => BindingResource::Sampler(sampler),
UnpreparedBindingResource::ShaderBuffer(shader_buffer) => {
// Fetch the raw buffer from the
// `shader_buffer_assets`. If it's not there,
// use the fallback buffer.
match shader_buffer_assets.get(shader_buffer.id()) {
Some(shader_buffer) => BindingResource::Buffer(BufferBinding {
buffer: &shader_buffer.buffer,
offset: 0,
size: None,
}),
None => BindingResource::Buffer(BufferBinding {
buffer: fallback_buffer,
offset: 0,
size: None,
}),
}
}
UnpreparedBindingResource::Data(_) => panic!("Data ranges have no binding resource"),
}
}
}
/// Converts a value to a [`ShaderType`] for use in a bind group.
///
/// This is automatically implemented for references that implement [`Into`].
/// Generally normal [`Into`] / [`From`] impls should be preferred, but
/// sometimes additional runtime metadata is required.
/// This exists largely to make some [`AsBindGroup`] use cases easier.
pub trait AsBindGroupShaderType<T: ShaderType> {
/// Return the `T` [`ShaderType`] for `self`. When used in [`AsBindGroup`]
/// derives, it is safe to assume that all images in `self` exist.
fn as_bind_group_shader_type(&self, images: &RenderAssets<GpuImage>) -> T;
}
impl<T, U: ShaderType> AsBindGroupShaderType<U> for T
whereView on GitHub (pinned to 396ca72708)
Solutions
- Route Data through the MaterialBindGroupAllocator (packing into a slotted buffer) rather than get_binding().
- Use Buffer/TextureView/Sampler variants for resources you intend to bind directly.
- Go through as_bind_group()/the standard material preparation, which handles Data packing.
Example fix
// before
let binding = unprepared.get_binding(); // panics on Data(_)
// after
match &unprepared {
UnpreparedBindingResource::Data(_) => { /* handled by MaterialBindGroupAllocator packing */ }
other => { let binding = other.get_binding(); }
} Defensive patterns
Strategy: type-guard
Type guard
fn unprepared_is_directly_bindable(res: &UnpreparedBindingResource) -> bool {
!matches!(res, UnpreparedBindingResource::Data(_))
} Prevention
- Handle the Data variant explicitly (allocator packing) whenever iterating unprepared bindings.
- Bind only Buffer/TextureView/Sampler variants directly.
- Use as_bind_group()/standard preparation instead of hand-building groups from unprepared data.
When it happens
Trigger: Calling get_binding() on UnpreparedBindingResource::Data - typical when hand-building a bind group from an unprepared material's binding list instead of using the allocator/packing path.
Common situations: Custom material code that iterates unprepared bindings uniformly; data-slot-based materials (values packed into shared buffers); migrating older code that assumed every binding had a direct resource.
Related errors
- You can't use `get_binding` with a `ShaderBuffer`; fetch the
- `OwnedData` has no binding resource
- Cannot call `ReflectComponent::reflect_mut` on component {na
- Cannot call `ReflectComponent::reflect_unchecked_mut` on com
- component should represent a type.
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/f61f654f1d017ef3.
Report an issue: GitHub.