gfx-rs/wgpu · error

iterator given to write_iter() produced {iter_len} elements

Error message

iterator given to write_iter() produced {iter_len} elements but must produce {self_len} elements

What it means

After consuming the user's iterator, `write_iter` verifies that every slot in the fixed-size buffer was filled; if slots remain, the iterator produced fewer than `self_len` elements and this panic fires. Unlike the over-length case, the count is inferred from unconsumed slots and reported in the message. Partial writes would leave stale data in the buffer, so they are rejected.

Source

Thrown at wgpu-types/src/write_only.rs:303

    {
        let self_len = self.len();
        let mut slot_iter = self.into_iter();

        // Call `for_each()` to take advantage of the iterator’s custom implementation, if it has
        // one. This may be superior to a `for` loop for `chain()`ed iterators and other cases where
        // the implementation of `Iterator::next()` would need to branch, and is typically
        // equivalent to a `for` loop for other iterators.
        iter.into_iter().for_each(|item| {
            let Some(slot) = slot_iter.next() else {
                panic!("iterator given to write_iter() produced more than {self_len} elements");
            };

            slot.write(item);
        });

        let remaining_len = slot_iter.len();
        if remaining_len != 0 {
            panic!(
                "iterator given to write_iter() produced {iter_len} elements \
                    but must produce {self_len} elements",
                // infer how many elements the iterator produced by how many of ours were consumed
                iter_len = self_len - remaining_len,
            );
        };
    }

    /// Writes copies of `value` to every element of `self`.
    ///
    /// # Example
    ///
    /// ```
    /// # use wgpu_types as wgpu;
    /// // Ordinarily you would get a `WriteOnly` from `wgpu::Buffer` instead.
    /// let mut buf = vec![0; 10];
    /// let mut wo = wgpu::WriteOnly::from_mut(buf.as_mut_slice());
    ///

View on GitHub (pinned to 3e11ff59bf)

Solutions

  1. Ensure the iterator yields exactly `self_len` elements: pad missing items with defaults (e.g. `.chain(std::iter::repeat(default))`) and take(self_len).
  2. Don't filter before writing; pre-materialize a correctly-sized Vec and assert its length equals the buffer's element count.
  3. Resize the buffer to match the actual data length instead of over-allocating.

Example fix

// before
buffer.write_iter(data.iter().filter(|x| x.valid).copied());
// after
let filtered: Vec<_> = data.iter().filter(|x| x.valid).copied().collect();
assert_eq!(filtered.len(), buffer.len());
buffer.write_iter(filtered);
Defensive patterns

Strategy: validation

Validate before calling

let capacity = buffer.size() as usize / item_size;
assert_eq!(
    data.len(), capacity,
    "write_iter: got {} items, buffer holds {}",
    data.len(), capacity
);
buffer.write_iter(data.iter().copied());

Prevention

When it happens

Trigger: Calling `write_iter` with an iterator that yields fewer elements than the buffer's slot count (`self_len`).

Common situations: Filtering iterators silently dropping elements (`.filter(...)`) before the write; short reads from a source collection; buffer allocated for a maximum count but the actual batch is smaller.

Related errors


AI-assisted analysis of gfx-rs/wgpu@3e11ff59bf (2026-09-03). Data as JSON: /api/errors/093a08c6514a1ed0. Report an issue: GitHub.