{"record":{"id":"e3545df693291a1a","repo":"gfx-rs/wgpu","slug":"slice-offset-slice-offset-is-out-of-range-for-bu","errorCode":null,"errorMessage":"slice offset {slice_offset} is out of range for buffer of size {whole_size}","messagePattern":"slice offset (.+?) is out of range for buffer of size (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"wgpu/src/api/buffer.rs","lineNumber":1056,"sourceCode":"    /// Copies all elements from src into `self`.\n    ///\n    /// The length of `src` must be the same as `self`.\n    ///\n    /// This method is equivalent to\n    /// [`self.slice(..).copy_from_slice(src)`][WriteOnly::copy_from_slice].\n    pub fn copy_from_slice(&mut self, src: &[u8]) {\n        self.slice(..).copy_from_slice(src)\n    }\n}\n\n#[track_caller]\nfn check_buffer_bounds(\n    whole_size: BufferAddress,\n    slice_offset: BufferAddress,\n    slice_size: BufferAddress,\n) {\n    if slice_offset > whole_size {\n        panic!(\n            \"slice offset {} is out of range for buffer of size {}\",\n            slice_offset, whole_size\n        );\n    }\n\n    // Detect integer overflow.\n    let end = slice_offset.checked_add(slice_size);\n    if end.is_none_or(|end| end > whole_size) {\n        panic!(\n            \"slice offset {} size {} is out of range for buffer of size {}\",\n            slice_offset, slice_size, whole_size\n        );\n    }\n}\n\n#[track_caller]\npub(crate) fn range_to_offset_size<S: RangeBounds<BufferAddress>>(\n    bounds: S,","sourceCodeStart":1038,"sourceCodeEnd":1074,"githubUrl":"https://github.com/gfx-rs/wgpu/blob/3e11ff59bf3f9795d285ecc045014089640d7248/wgpu/src/api/buffer.rs#L1038-L1074","documentation":"Buffer::slice validates that the requested slice offset does not exceed the buffer's total size via check_buffer_bounds, panicking if offset > whole_size. This is a debug-time safety check so that out-of-range buffer slicing fails immediately with a clear message instead of producing invalid bindings.","triggerScenarios":"Calling buffer.slice(offset..end) (or related APIs) with an offset larger than the buffer's size — e.g. a hardcoded offset beyond the allocation, or a size computed from a different (smaller) buffer.","commonSituations":"Binding uniform buffers at computed offsets where the offset table no longer matches the buffer sizes (stride changes, alignment fixes, buffer shrunk), or typos like buffer.slice(size..size + x) on a buffer of length size.","solutions":["Verify the slice offset against buffer.size() before slicing; clamp or return early if offset > size.","Fix the constant/stride that produced the offset — often an alignment (256-byte uniform) or struct-size mismatch.","Check that you are slicing the intended buffer, not one allocated with a smaller size."],"exampleFix":"// before\nlet view = buffer.slice(1024..1024 + size); // buffer.size() == 512\n// after\nassert!(1024 + size <= buffer.size(), \"slice out of bounds\");\nlet view = buffer.slice(0..size);","handlingStrategy":"validation","validationCode":"if slice_offset > buffer.size() {\n    return Err(format!(\"offset {slice_offset} exceeds buffer size {}\", buffer.size()));\n}\nlet view = buffer.slice(slice_offset..end);","typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| buffer.slice(off..end)));","preventionTips":["Compute slice ranges from buffer.size() rather than hardcoded offsets.","Keep a registry of region offsets/sizes per buffer and validate against it.","Recheck offsets after any change to struct layouts or uniform strides."],"tags":["panic","rust","buffer","bounds"],"backgroundTag":"buffer-out-of-bounds","analyzedSha":"3e11ff59bf3f9795d285ecc045014089640d7248","analyzedAt":"2026-09-03T01:43:21.459Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}