bevyengine/bevy · warning · WriteBufferRangeError

NoValuesToUpload

NoValuesToUpload

Error message

there are no values to upload

What it means

WriteBufferRangeError::NoValuesToUpload is returned when write_buffer_range is called while the CPU-side values vector is empty (buffer_vec.rs:201-203). There is nothing to write, so the method refuses rather than performing a zero-byte upload. It is effectively a benign precondition failure signalling an empty buffer.

Source

Thrown at crates/bevy_render/src/render_resource/buffer_vec.rs:984

    /// Pushes `count` copies of `T::default` to the array.
    pub fn push_multiple_init(&mut self, count: usize) -> usize {
        debug_assert_eq!(self.uninit_element_count, 0);
        let index = self.values.len();
        self.values.extend(iter::repeat_n(T::default(), count));
        index
    }
}

/// Error returned when `write_buffer_range` fails
///
/// See [`RawBufferVec::write_buffer_range`] [`BufferVec::write_buffer_range`]
#[derive(Debug, Eq, PartialEq, Copy, Clone, Error)]
pub enum WriteBufferRangeError {
    #[error("the range is bigger than the capacity of the buffer")]
    RangeBiggerThanBuffer,
    #[error("the gpu buffer is not initialized")]
    BufferNotInitialized,
    #[error("there are no values to upload")]
    NoValuesToUpload,
}

#[inline]
#[cfg_attr(
    not(feature = "type_label_buffers"),
    expect(
        clippy::extra_unused_type_parameters,
        reason = "conditional compilation"
    )
)]
pub(crate) fn make_buffer_label<'a, T>(label: &'a Option<String>) -> Option<&'a str> {
    #[cfg(feature = "type_label_buffers")]
    if label.is_none() {
        return Some(core::any::type_name::<T>());
    }
    label.as_deref()
}

View on GitHub (pinned to 396ca72708)

Solutions

  1. Guard the call: only write when !vec.is_empty().
  2. Treat the variant as benign in match arms (debug-level log or ignore) if empty states are expected.
  3. If data should exist, check why the population system produced no values.

Example fix

// before
vec.clear();
vec.write_buffer_range(queue, 0..vec.len())?; // Err(NoValuesToUpload) on empty vec

// after
if !vec.is_empty() {
    vec.write_buffer_range(queue, 0..vec.len())?;
}
Defensive patterns

Strategy: validation

Validate before calling

if !vec.is_empty() {
    vec.write_buffer_range(queue, 0..vec.len())?;
}

Try / catch

match vec.write_buffer_range(queue, 0..vec.len()) {
    Err(WriteBufferRangeError::NoValuesToUpload) => { /* nothing to upload this frame */ }
    other => other?,
}

Prevention

When it happens

Trigger: Calling write_buffer_range on a cleared or never-filled BufferVec - e.g. after clear() when all entities were removed, or on the first frame before any push.

Common situations: Per-frame instance buffers whose population varies (all lights removed, all meshes culled/removed); startup frames before data arrives; loops that write on a schedule regardless of whether items exist.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/b35fff1cfa26db5c. Report an issue: GitHub.