{"record":{"id":"d2e44716a72360da","repo":"bevyengine/bevy","slug":"the-asset-type-does-not-support-extraction-to-clo","errorCode":null,"errorMessage":"The asset type does not support extraction. To clone the asset to the renderworld, use `RenderAssetUsages::default()`","messagePattern":"The asset type does not support extraction\\. To clone the asset to the renderworld, use `RenderAssetUsages::default\\(\\)`","errorType":"exception","errorClass":"AssetExtractionError","httpStatus":null,"severity":"error","filePath":"crates/bevy_render/src/render_asset.rs","lineNumber":36,"sourceCode":"\n#[derive(Debug, Error)]\npub enum PrepareAssetError<E: Send + Sync + 'static> {\n    #[error(\"Failed to prepare asset\")]\n    RetryNextUpdate(E),\n    #[error(\"Failed to build bind group: {0}\")]\n    AsBindGroupError(AsBindGroupError),\n}\n\n/// The system set during which we extract modified assets to the render world.\n#[derive(SystemSet, Clone, PartialEq, Eq, Debug, Hash)]\npub struct AssetExtractionSystems;\n\n/// Error returned when an asset due for extraction has already been extracted\n#[derive(Debug, Error)]\npub enum AssetExtractionError {\n    #[error(\"The asset has already been extracted\")]\n    AlreadyExtracted,\n    #[error(\"The asset type does not support extraction. To clone the asset to the renderworld, use `RenderAssetUsages::default()`\")]\n    NoExtractionImplementation,\n}\n\n/// Describes how an asset gets extracted and prepared for rendering.\n///\n/// In the [`ExtractSchedule`] step the [`RenderAsset::SourceAsset`] is transferred\n/// from the \"main world\" into the \"render world\".\n///\n/// After that in the [`RenderSystems::PrepareAssets`] step the extracted asset\n/// is transformed into its GPU-representation of type [`RenderAsset`].\npub trait RenderAsset: Send + Sync + 'static + Sized {\n    /// The representation of the asset in the \"main world\".\n    type SourceAsset: Asset + Clone;\n\n    /// Specifies all ECS data required by [`RenderAsset::prepare_asset`].\n    ///\n    /// For convenience use the [`lifetimeless`](bevy_ecs::system::lifetimeless) [`SystemParam`].\n    type Param: SystemParam;","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_render/src/render_asset.rs#L18-L54","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nimpl RenderAsset for GpuCustomMesh {\n    type SourceAsset = CustomMesh;\n    fn asset_usage(_s: &CustomMesh) -> RenderAssetUsages {\n        RenderAssetUsages::MAIN_WORLD // extraction path, but take_gpu_data not implemented\n    }\n    // ...\n}\n\n// after (option A): clone instead of extract\nfn asset_usage(_s: &CustomMesh) -> RenderAssetUsages {\n    RenderAssetUsages::default()\n}\n\n// after (option B): keep MAIN_WORLD usage, implement extraction\nfn take_gpu_data(\n    source: &mut CustomMesh,\n    _previous: Option<&Self>,\n) -> Result<CustomMesh, AssetExtractionError> {\n    Ok(core::mem::take(&mut source.gpu_data))\n}","handlingStrategy":"validation","validationCode":"// Before opting into the extraction path, confirm take_gpu_data is implemented\n// for your RenderAsset; otherwise keep the clone-based default usages.\nconst EXTRACTION_IMPLEMENTED: bool = false;\n\nfn asset_usage(source: &CustomAsset) -> RenderAssetUsages {\n    if EXTRACTION_IMPLEMENTED {\n        RenderAssetUsages::MAIN_WORLD\n    } else {\n        RenderAssetUsages::default() // clone to the render world\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["bevy","render-asset","asset-usage","extraction","rust"],"backgroundTag":"not-implemented","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}