emilk/egui · error
You must call .update_buffers() before .render()
Error message
You must call .update_buffers() before .render()
What it means
In egui-wgpu's renderer, render() advances pre-built buffer slice iterators for each mesh. If the iterators are empty, render was called without a prior update_buffers() call, so the slices from the uploaded buffers don't match the painted primitives. The library panics because continuing would render garbage indices.
Source
Thrown at crates/egui-wgpu/src/renderer.rs:552
size_in_pixels[1] as f32,
0.0,
1.0,
);
render_pass.set_pipeline(&self.pipeline);
render_pass.set_bind_group(0, &self.uniform_bind_group, &[]);
needs_reset = false;
}
{
let rect = ScissorRect::new(clip_rect, pixels_per_point, size_in_pixels);
if rect.width == 0 || rect.height == 0 {
// Skip rendering zero-sized clip areas.
if let Primitive::Mesh(_) = primitive {
// If this is a mesh, we need to advance the index and vertex buffer iterators:
index_buffer_slices
.next()
.expect("You must call .update_buffers() before .render()");
vertex_buffer_slices
.next()
.expect("You must call .update_buffers() before .render()");
}
continue;
}
render_pass.set_scissor_rect(rect.x, rect.y, rect.width, rect.height);
}
match primitive {
Primitive::Mesh(mesh) => {
let index_buffer_slice = index_buffer_slices
.next()
.expect("You must call .update_buffers() before .render()");
let vertex_buffer_slice = vertex_buffer_slices
.next()
.expect("You must call .update_buffers() before .render()");View on GitHub (pinned to 441971a776)
Solutions
- Call renderer.update_buffers(device, queue, encoder, clipped_primitives, screen_descriptor) before render and pass the returned Vec<BufferDimensions> usage onward.
- Use the standard egui_wgpu::Renderer::render flow (it manages update_buffers internally) rather than a custom one.
- Update integration code copied from outdated examples to the current egui-wgpu render pattern.
Example fix
// before renderer.render(&mut render_pass, &clipped_primitives, &screen); // after let buffer_slices = renderer.update_buffers(&device, &queue, &mut encoder, &clipped_primitives, &screen); renderer.render(&mut render_pass, &clipped_primitives, &buffer_slices, &screen);
Defensive patterns
Strategy: validation
Validate before calling
// Ensure this ran in the same frame: // let slices = renderer.update_buffers(&device, &queue, &mut encoder, &clipped_primitives, &screen_descriptor);
Type guard
fn slices_ready(slices: &[egui_wgpu::BufferDimensions], prims: &[ClippedPrimitive]) -> bool { !prims.iter().any(|p| matches!(p.primitive, Primitive::Mesh(_))) || !slices.is_empty() } Try / catch
// Panic in release too; not catchable per-call. Prevent by structuring code so update_buffers always precedes render.
Prevention
- Always call update_buffers immediately before render with identical primitives.
- Pass update_buffers' return value directly into render.
- Follow the current official egui-wgpu/eframe integration example.
When it happens
Trigger: Calling CallbackTrait::render (or egui_wgpu::Renderer::render) directly without calling renderer.update_buffers(...) first for the same screen descriptor and clipped primitives, in a custom integration or custom paint callback.
Common situations: Custom egui-wgpu integrations written before/without update_buffers (API added to fix multi-mesh rendering); users overriding render in a paint callback; porting older integration code to a newer egui-wgpu where render no longer does buffer uploads itself.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Tried to update a texture that has not been allocated yet.
- Failed to create render state
- Failed to create staging buffer for index data. Index count:
- Failed to create staging buffer for vertex data. Vertex coun
- Shape::Callback passed to Tessellator
AI-assisted analysis of emilk/egui@441971a776 (2026-09-12).
Data as JSON: /api/errors/506981f1f72cf9ff.
Report an issue: GitHub.