bevyengine/bevy · error · IntoDynamicImageError
Image has no texture data
Error message
Image has no texture data
What it means
IntoDynamicImageError::UninitializedImage is returned at the top of Image::try_into_dynamic (image_texture_conversion.rs:161-163) when self.data is None — the Image has no CPU-side bytes. This is the conversion-API twin of TextureAccessError::Uninitialized: the asset was loaded with RenderAssetUsages::RENDER_WORLD (CPU copy dropped after GPU upload) or otherwise constructed without data (Image::default / new_uninit). Bevy cannot produce a DynamicImage from texture bytes it no longer holds.
Source
Thrown at crates/bevy_image/src/image_texture_conversion.rs:208
self.texture_descriptor.format,
))
}
}
/// Errors that occur while converting an [`Image`] into a [`DynamicImage`]
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum IntoDynamicImageError {
/// Conversion into dynamic image not supported for source format.
#[error("Conversion into dynamic image not supported for {0:?}.")]
UnsupportedFormat(TextureFormat),
/// Encountered an unknown error during conversion.
#[error("Failed to convert into {0:?}.")]
UnknownConversionError(TextureFormat),
/// Tried to convert an image that has no texture data
#[error("Image has no texture data")]
UninitializedImage,
}
#[cfg(test)]
mod test {
use image::{GenericImage, Rgba};
use super::*;
#[test]
fn two_way_conversion() {
// Check to see if color is preserved through an rgba8 conversion and back.
let mut initial = DynamicImage::new_rgba8(1, 1);
initial.put_pixel(0, 0, Rgba::from([132, 3, 7, 200]));
let image = Image::from_dynamic(initial.clone(), true, RenderAssetUsages::RENDER_WORLD);
// NOTE: Fails if `is_srgb = false` or the dynamic image is of the type rgb8.View on GitHub (pinned to 396ca72708)
Solutions
- Load/retain the texture with RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD (default) so data survives on CPU.
- Check image.data.is_some() before calling try_into_dynamic and report a precise error.
- If the image is RENDER_WORLD-only, re-request the original asset from the AssetServer instead of the GPU-side handle.
- Never construct images you intend to convert with Image::default() or new_uninit without filling data.
Example fix
// before
server.load_with_settings("photo.png", |s: &mut ImageLoaderSettings| {
s.asset_usage = RenderAssetUsages::RENDER_WORLD;
});
let dyn_img = image.try_into_dynamic()?; // Err(UninitializedImage)
// after — keep MAIN_WORLD so data stays on CPU
s.asset_usage = RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD; Defensive patterns
Strategy: validation
Validate before calling
// guard before converting
if image.data.is_none() {
warn!("image has no CPU data (RENDER_WORLD-only?); cannot convert");
return;
}
let dyn_img = image.try_into_dynamic()?; Type guard
fn convertible_now(image: &Image) -> bool {
image.data.is_some()
&& matches!(
image.texture_descriptor.format,
TextureFormat::R8Unorm
| TextureFormat::Rg8Unorm
| TextureFormat::Rgba8UnormSrgb
| TextureFormat::Bgra8UnormSrgb
| TextureFormat::Bgra8Unorm
)
} Try / catch
match image.try_into_dynamic() {
Err(IntoDynamicImageError::UninitializedImage) => {
// re-load source with MAIN_WORLD usage, then retry
}
Err(IntoDynamicImageError::UnsupportedFormat(f)) => { /* convert format first */ }
Err(IntoDynamicImageError::UnknownConversionError(f)) => { /* fix data/extent mismatch */ }
Ok(dyn) => { /* ... */ }
} Prevention
- Load images you plan to post-process with RenderAssetUsages::MAIN_WORLD included.
- Avoid .data.take() on images you still need to convert.
- Centralize DynamicImage extraction in one helper that checks data presence first.
When it happens
Trigger: Calling image.try_into_dynamic() on an image loaded with asset_usage = RenderAssetUsages::RENDER_WORLD; on Image::default(); on any image whose data field is None (e.g. after data was taken out with .data.take()).
Common situations: Screenshot/thumbnail code running on render-target images created RENDER_WORLD-only; memory-optimized builds that drop CPU copies; extracting a DynamicImage from a handle returned by the render pipeline rather than the original asset.
Related errors
- Conversion into dynamic image not supported for {0:?}.
- Failed to convert into {0:?}.
- image data is not initialized
- Could not load texture file: {0}
- Error reading image file {path}: {error}.
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/b452698ad46be0e3.
Report an issue: GitHub.