bevyengine/bevy · critical
`OwnedData` has no binding resource
Error message
`OwnedData` has no binding resource
What it means
OwnedBindingResource::get_binding() (bind_group.rs:832) panics on the Data variant because OwnedData does not itself correspond to any binding: it is an unstructured value that must be packed into a buffer by the MaterialBindGroupAllocator before anything can be bound. Calling get_binding() on it bypasses that required packing step.
Source
Thrown at crates/bevy_render/src/render_resource/bind_group.rs:832
/// Creates a [`BindingResource`] reference to this
/// [`OwnedBindingResource`].
///
/// Note that this operation panics if passed a
/// [`OwnedBindingResource::Data`], because [`OwnedData`] doesn't itself
/// correspond to any binding and instead requires the
/// `MaterialBindGroupAllocator` to pack it into a buffer.
pub fn get_binding(&self) -> BindingResource<'_> {
match self {
OwnedBindingResource::Buffer(buffer) => buffer.as_entire_binding(),
OwnedBindingResource::ShaderBuffer(_) => {
panic!(
"You can't use `get_binding` with a `ShaderBuffer`; fetch the buffer from \
the `RenderAssets<GpuShaderBuffer>` instead"
)
}
OwnedBindingResource::TextureView(_, view) => BindingResource::TextureView(view),
OwnedBindingResource::Sampler(_, sampler) => BindingResource::Sampler(sampler),
OwnedBindingResource::Data(_) => panic!("`OwnedData` has no binding resource"),
}
}
}
impl UnpreparedBindingResource {
/// Creates a [`BindingResource`] reference to this
/// [`UnpreparedBindingResource`].
///
/// Note that this operation panics if passed a
/// [`UnpreparedBindingResource::Data`], because the range doesn't itself
/// correspond to any binding and instead requires the
/// `MaterialBindGroupAllocator` to pack it into a buffer.
pub fn get_binding<'a>(
&'a self,
fallback_buffer: &'a FallbackBuffer,
shader_buffer_assets: &'a RenderAssets<GpuShaderBuffer>,
) -> BindingResource<'a> {
match self {View on GitHub (pinned to 396ca72708)
Solutions
- Let the MaterialBindGroupAllocator pack OwnedData into its slotted buffer and bind at the allocated offset instead of calling get_binding().
- If you need a directly bindable resource, store the data in a real wgpu buffer and produce OwnedBindingResource::Buffer rather than Data.
- Route custom materials through the standard preparation pipeline.
Example fix
// before
let binding = owned_resource.get_binding(); // panics on Data variant
// after: only bind variants that map to a real binding resource
if matches!(owned_resource, OwnedBindingResource::Data(_)) {
// let the MaterialBindGroupAllocator pack it into its buffer
} else {
let binding = owned_resource.get_binding();
} Defensive patterns
Strategy: type-guard
Type guard
fn is_directly_bindable(res: &OwnedBindingResource) -> bool {
!matches!(res, OwnedBindingResource::Data(_))
} Prevention
- Route OwnedData through the MaterialBindGroupAllocator instead of converting it to a binding.
- Use OwnedBindingResource::Buffer when you need a directly bindable GPU resource.
- Match on variants in generic binding code rather than assuming uniformity.
When it happens
Trigger: Calling get_binding() on OwnedBindingResource::Data - e.g. custom code building a bind group from a material's owned binding resources without going through the MaterialBindGroupAllocator.
Common situations: Hand-rolled bind group construction for materials that use data slots; custom AsBindGroup implementations iterating owned resources; porting code from buffer-based bindings to packed data.
Related errors
- You can't use `get_binding` with a `ShaderBuffer`; fetch the
- Data ranges have no binding resource
- Failed to get buffer
- Failed to get buffer
- Cannot call `ReflectComponent::reflect_mut` on component {na
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/67139dbda6d833ec.
Report an issue: GitHub.