{"record":{"id":"f1a4b95744610f31","repo":"bevyengine/bevy","slug":"mesh-access-error-0-f1a4b9","errorCode":null,"errorMessage":"Mesh access error: {0}","messagePattern":"Mesh access error: (.+?)","errorType":"exception","errorClass":"MeshMergeDuplicateVerticesError","httpStatus":null,"severity":"error","filePath":"crates/bevy_mesh/src/mesh.rs","lineNumber":3018,"sourceCode":"                            was not specified with `MeshDeserializer::add_custom_vertex_attribute`. Ignoring.\"\n                        );\n                        return None;\n                    };\n                    Some((id, data))\n                })\n                .collect()),\n            indices: serialized_mesh.indices.into(),\n            ..Mesh::new(serialized_mesh.primitive_topology, RenderAssetUsages::default())\n        }\n    }\n}\n\n/// Error that can occur when calling [`Mesh::merge_duplicate_vertices`]\n#[derive(Error, Debug, Clone)]\npub enum MeshMergeDuplicateVerticesError {\n    #[error(\"Index attribute already set.\")]\n    IndicesAlreadySet,\n    #[error(\"Mesh access error: {0}\")]\n    MeshAccessError(#[from] MeshAccessError),\n}\n\n/// Error that can occur when calling [`Mesh::merge`].\n#[derive(Error, Debug, Clone)]\npub enum MeshMergeError {\n    #[error(\"Incompatible vertex attribute types: {} and {}\", self_attribute.name, other_attribute.map(|a| a.name).unwrap_or(\"None\"))]\n    IncompatibleVertexAttributes {\n        self_attribute: MeshVertexAttribute,\n        other_attribute: Option<MeshVertexAttribute>,\n    },\n    #[error(\n        \"Incompatible primitive topologies: {:?} and {:?}\",\n        self_primitive_topology,\n        other_primitive_topology\n    )]\n    IncompatiblePrimitiveTopology {\n        self_primitive_topology: PrimitiveTopology,","sourceCodeStart":3000,"sourceCodeEnd":3036,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_mesh/src/mesh.rs#L3000-L3036","documentation":"MeshMergeDuplicateVerticesError::MeshAccessError (crates/bevy_mesh/src/mesh.rs:3018) wraps the MeshAccessError produced while merge_duplicate_vertices reads vertex data. In this code path the NotFound variant is tolerated (missing indices are expected), so the error that actually surfaces is MeshAccessError::ExtractedToRenderWorld: the mesh's RenderAssetUsages excluded MAIN_WORLD, so its vertex/index data was moved to the render world and is no longer readable from the app world.","triggerScenarios":"Creating a Mesh with RenderAssetUsages::RENDER_WORLD (main-world data dropped after extraction) and then calling merge_duplicate_vertices() on it after the asset has been prepared/extracted once.","commonSituations":"Memory-optimized asset pipelines that mark runtime-generated meshes as render-world-only; calling mesh post-processing (welding, normals) from a system that runs after rendering has already consumed the asset.","solutions":["Create the mesh with RenderAssetUsages::default() (MAIN_WORLD | RENDER_WORLD) so attributes stay readable","Do all CPU-side processing (merge_duplicate_vertices, compute_smooth_normals) before spawning/adding the render-world-only mesh","If the data is already extracted, re-create or re-import the mesh instead of trying to recover it"],"exampleFix":"// before: render-world-only mesh\nlet mut mesh = Mesh::new(PrimitiveTopology::TriangleList, RenderAssetUsages::RENDER_WORLD);\nmesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);\n// ...after the renderer extracts it:\nmesh.merge_duplicate_vertices(); // Err(MeshAccessError::ExtractedToRenderWorld)\n\n// after: keep data in the main world too\nlet mut mesh = Mesh::new(PrimitiveTopology::TriangleList, RenderAssetUsages::default());\nmesh.merge_duplicate_vertices().unwrap();","handlingStrategy":"validation","validationCode":"fn cpu_accessible(mesh: &Mesh) -> bool {\n    mesh.asset_usage().contains(RenderAssetUsages::MAIN_WORLD)\n}\n\nif cpu_accessible(&mesh) {\n    mesh.merge_duplicate_vertices()?;\n}","typeGuard":null,"tryCatchPattern":"if let Err(MeshMergeDuplicateVerticesError::MeshAccessError(\n    MeshAccessError::ExtractedToRenderWorld,\n)) = mesh.merge_duplicate_vertices()\n{\n    // re-create the mesh from source data with RenderAssetUsages::default()\n}","preventionTips":["Only use RenderAssetUsages::RENDER_WORLD for meshes you will never touch on the CPU again","Finish all CPU-side processing (weld, normals, tangents) before adding the mesh to Assets<Mesh>","Centralize RenderAssetUsages choice in one factory function so projects stay auditable"],"tags":["bevy","mesh","render-asset-usage","asset-lifetime","merge-duplicate-vertices"],"backgroundTag":"mesh-extracted-to-render-world","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}