{"record":{"id":"ddde4ef4186aa55c","repo":"bevyengine/bevy","slug":"failed-to-map-buffer","errorCode":null,"errorMessage":"Failed to map buffer","messagePattern":"Failed to map buffer","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/bevy_render/src/gpu_readback.rs","lineNumber":409,"sourceCode":"            }\n        }\n    }\n}\n\n/// Move requested readbacks to mapped readbacks after commands have been submitted in render system\n#[expect(\n    clippy::drain_collect,\n    reason = \"draining preserves the capacity of `requested`, which is refilled every frame\"\n)]\nfn map_buffers(mut readbacks: ResMut<GpuReadbacks>) {\n    let requested = readbacks.requested.drain(..).collect::<Vec<GpuReadback>>();\n    for readback in requested {\n        let slice = readback.buffer.slice(..);\n        let entity = readback.entity;\n        let buffer = readback.buffer.clone();\n        let tx = readback.tx.clone();\n        slice.map_async(wgpu::MapMode::Read, move |res| {\n            res.expect(\"Failed to map buffer\");\n            let buffer_slice = buffer.slice(..);\n            let data = buffer_slice.get_mapped_range().unwrap();\n            let result = Vec::from(&*data);\n            drop(data);\n            buffer.unmap();\n            if let Err(e) = tx.try_send((entity, buffer, result)) {\n                debug!(\"Failed to send readback result: {}\", e);\n            }\n        });\n        readbacks.mapped.push(readback);\n    }\n}\n\n// Utils\n\n/// Round up a given value to be a multiple of [`wgpu::COPY_BYTES_PER_ROW_ALIGNMENT`].\npub(crate) const fn align_byte_size(value: u32) -> u32 {\n    RenderDevice::align_copy_bytes_per_row(value as usize) as u32","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/bevyengine/bevy/blob/4805ca792c3e94eef07afd6fa9a2712f388c9a67/crates/bevy_render/src/gpu_readback.rs#L391-L427","documentation":"After submitted commands complete, bevy's readback system calls `map_async(Read, ...)` on each staging buffer and unwraps the callback result with `.expect(\"Failed to map buffer\")`. A mapping failure means wgpu refused the map: the buffer was already mapped or destroyed, or the device was lost.","triggerScenarios":"A requested GPU readback whose staging buffer cannot be mapped — device loss between request and map, buffer destroyed/invalidated first, or abnormal shutdown while readbacks are still in flight.","commonSituations":"App exit during an in-flight readback; driver reset mid-session; dropping or mutating the source ShaderBuffer in the same frame the readback is requested.","solutions":["Keep the app and device alive until pending readbacks resolve (take the result from the spawned GpuReadback entity before exiting)","Don't despawn readback entities or drop the source buffer before results arrive","If it happens mid-run, look for the original device-loss error elsewhere in wgpu logs; this panic is usually a symptom, not the cause"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Await readback results (via the spawned GpuReadback entity) before exiting or dropping resources","Don't despawn readback entities mid-flight","Treat a map failure as a symptom of device loss; check earlier wgpu errors first"],"tags":["bevy","gpu-readback","wgpu","buffer-mapping","panic"],"backgroundTag":"gpu-buffer-map-failed","analyzedSha":"4805ca792c3e94eef07afd6fa9a2712f388c9a67","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}