bevyengine/bevy · error · TextureAccessError

image data is not initialized

Error message

image data is not initialized

What it means

TextureAccessError::Uninitialized is returned by Image::pixel_bytes and Image::pixel_bytes_mut (crates/bevy_image/src/image.rs:1702, 1714) when the Image's data field (pub data: Option<Vec<u8>>) is None. That means there is no CPU-side copy: either the image was created with Image::new_uninit and never filled, or it was loaded with RenderAssetUsages::RENDER_WORLD so Bevy dropped the CPU bytes after uploading to the GPU. The variant's doc comment points to RenderAssetUsages for controlling when data is moved.

Source

Thrown at crates/bevy_image/src/image.rs:2279

    /// how to retain it if necessary.
    #[error("image data is not initialized")]
    Uninitialized,
    /// The texture's dimension was different than indicated by the accessor used.
    #[error("attempt to access texture with different dimension")]
    WrongDimension,
}

/// An error that occurs when loading a texture.
#[derive(Error, Debug)]
pub enum TextureError {
    /// Image MIME type is invalid.
    #[error("invalid image mime type: {0}")]
    InvalidImageMimeType(String),
    /// Image extension is invalid.
    #[error("invalid image extension: {0}")]
    InvalidImageExtension(String),
    /// Failed to load an image.
    #[error("failed to load an image: {0}")]
    ImageError(#[from] image::ImageError),
    /// Texture format isn't supported.
    #[error("unsupported texture format: {0}")]
    UnsupportedTextureFormat(String),
    /// Supercompression isn't supported.
    #[error("supercompression not supported: {0}")]
    SuperCompressionNotSupported(String),
    /// Failed to decompress an image.
    #[error("failed to decompress an image: {0}")]
    SuperDecompressionError(String),
    /// Invalid data.
    #[error("invalid data: {0}")]
    InvalidData(String),
    /// Transcode error.
    #[error("transcode error: {0}")]
    TranscodeError(String),
    /// Format requires transcoding.
    #[error("format requires transcoding: {0:?}")]

View on GitHub (pinned to 221e52ae32)

Solutions

  1. Load the asset with the default RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD so the CPU copy survives the GPU upload.
  2. If you used Image::new_uninit, fill it first (Image::new, Image::new_fill, or a write via pixel_bytes_mut) before any read.
  3. If the handle already points at a RENDER_WORLD-only asset, re-load the source file from the AssetServer or keep a second MAIN_WORLD copy reserved for CPU reads.

Example fix

// before — CPU data is dropped after upload
server.load_with_settings("tex.png", |s: &mut ImageLoaderSettings| {
    s.asset_usage = RenderAssetUsages::RENDER_WORLD;
});
let bytes = image.pixel_bytes(UVec3::ZERO)?; // Err(Uninitialized)

// after — retain the CPU copy
s.asset_usage = RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD;
Defensive patterns

Strategy: validation

Validate before calling

// before pixel_bytes / pixel_bytes_mut / get_color_at:
if image.data.as_ref().is_some_and(|d| !d.is_empty()) {
    let bytes = image.pixel_bytes(UVec3::new(x, y, 0))?;
}

Type guard

fn has_cpu_data(image: &Image) -> bool {
    image.data.as_ref().is_some_and(|d| !d.is_empty())
}

Try / catch

match image.pixel_bytes(coords) {
    Ok(bytes) => { /* ... */ }
    Err(TextureAccessError::Uninitialized) => {
        // re-load with MAIN_WORLD usage or keep a CPU copy
    }
    Err(e) => warn!("pixel access failed: {e}"),
}

Prevention

When it happens

Trigger: Calling pixel_bytes/pixel_bytes_mut (or the get_color_at*/set_color_at* accessors built on them) on an Image whose data is None — created via Image::new_uninit without a subsequent write, or loaded through ImageLoaderSettings with asset_usage = RenderAssetUsages::RENDER_WORLD (CPU copy freed after GPU upload).

Common situations: Games that set RENDER_WORLD-only usage to halve texture memory, then later try to read pixels for screenshots, picking, or serialization; images created with new_uninit awaiting an async fill; code that assumes texture data is always resident on CPU after load.

Related errors


AI-assisted analysis of bevyengine/bevy@221e52ae32 (2026-08-20). Data as JSON: /api/errors/4ab72f13411250e0. Report an issue: GitHub.