bevyengine/bevy · error · AssetExtractionError
The asset type does not support extraction. To clone the ass
Error message
The asset type does not support extraction. To clone the asset to the renderworld, use `RenderAssetUsages::default()`
What it means
Returned by RenderAsset::take_gpu_data (render_asset.rs:104) when a RenderAsset implementation keeps the default method body. 'take_gpu_data' is the extraction hook used when an asset is NOT simply cloned to the render world; if you opt out of cloning (e.g. RenderAssetUsages::MAIN_WORLD only) but never implement extraction, the extraction system gets this error. The message tells you the fix: use RenderAssetUsages::default() (MAIN_WORLD | RENDER_WORLD) so the asset is cloned instead of extracted.
Source
Thrown at crates/bevy_render/src/render_asset.rs:36
#[derive(Debug, Error)]
pub enum PrepareAssetError<E: Send + Sync + 'static> {
#[error("Failed to prepare asset")]
RetryNextUpdate(E),
#[error("Failed to build bind group: {0}")]
AsBindGroupError(AsBindGroupError),
}
/// The system set during which we extract modified assets to the render world.
#[derive(SystemSet, Clone, PartialEq, Eq, Debug, Hash)]
pub struct AssetExtractionSystems;
/// Error returned when an asset due for extraction has already been extracted
#[derive(Debug, Error)]
pub enum AssetExtractionError {
#[error("The asset has already been extracted")]
AlreadyExtracted,
#[error("The asset type does not support extraction. To clone the asset to the renderworld, use `RenderAssetUsages::default()`")]
NoExtractionImplementation,
}
/// Describes how an asset gets extracted and prepared for rendering.
///
/// In the [`ExtractSchedule`] step the [`RenderAsset::SourceAsset`] is transferred
/// from the "main world" into the "render world".
///
/// After that in the [`RenderSystems::PrepareAssets`] step the extracted asset
/// is transformed into its GPU-representation of type [`RenderAsset`].
pub trait RenderAsset: Send + Sync + 'static + Sized {
/// The representation of the asset in the "main world".
type SourceAsset: Asset + Clone;
/// Specifies all ECS data required by [`RenderAsset::prepare_asset`].
///
/// For convenience use the [`lifetimeless`](bevy_ecs::system::lifetimeless) [`SystemParam`].
type Param: SystemParam;View on GitHub (pinned to 396ca72708)
Solutions
- Return RenderAssetUsages::default() from asset_usage() so Bevy clones the asset into the render world instead of extracting it.
- Or override take_gpu_data to move the GPU-heavy data out of the source asset (e.g. core::mem::take) and return it as Ok(..).
- If you control the plugin setup and never want this asset on the GPU, do not register RenderAssetPlugin for that type so extraction never runs.
Example fix
// before
impl RenderAsset for GpuCustomMesh {
type SourceAsset = CustomMesh;
fn asset_usage(_s: &CustomMesh) -> RenderAssetUsages {
RenderAssetUsages::MAIN_WORLD // extraction path, but take_gpu_data not implemented
}
// ...
}
// after (option A): clone instead of extract
fn asset_usage(_s: &CustomMesh) -> RenderAssetUsages {
RenderAssetUsages::default()
}
// after (option B): keep MAIN_WORLD usage, implement extraction
fn take_gpu_data(
source: &mut CustomMesh,
_previous: Option<&Self>,
) -> Result<CustomMesh, AssetExtractionError> {
Ok(core::mem::take(&mut source.gpu_data))
} Defensive patterns
Strategy: validation
Validate before calling
// Before opting into the extraction path, confirm take_gpu_data is implemented
// for your RenderAsset; otherwise keep the clone-based default usages.
const EXTRACTION_IMPLEMENTED: bool = false;
fn asset_usage(source: &CustomAsset) -> RenderAssetUsages {
if EXTRACTION_IMPLEMENTED {
RenderAssetUsages::MAIN_WORLD
} else {
RenderAssetUsages::default() // clone to the render world
}
} Prevention
- Default to RenderAssetUsages::default() unless you have a measured reason to avoid cloning.
- If you return MAIN_WORLD-only usages, implement take_gpu_data in the same change.
- Write a unit test that runs the extraction schedule over your asset to catch the error at test time.
When it happens
Trigger: Implementing RenderAsset for a custom asset, overriding asset_usage() to return something other than RenderAssetUsages::default() (typically MAIN_WORLD-only to avoid duplicating data across worlds), and leaving take_gpu_data at its default which unconditionally returns Err(AssetExtractionError::NoExtractionImplementation).
Common situations: Custom mesh/texture-like assets where the author wants zero-copy transfer to the render world; Bevy version upgrades that introduced the take_gpu_data/AssetExtractionError API; code copied from examples that use RenderAssetUsages::MAIN_WORLD without the matching extraction impl.
Related errors
- Mesh access error: {0}
- mesh access error: {0}
- The mesh vertex/index data has been extracted to the RenderW
- Color compression flag must be `COMPRESS_COLOR_FLOAT16` or `
- Field name should exist
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/d2e44716a72360da.
Report an issue: GitHub.