bevyengine/bevy · error

Failed to calculate aspect ratio for Cluster: screen dimensi

Error message

Failed to calculate aspect ratio for Cluster: screen dimensions must be positive, non-zero values

What it means

bevy_light's ClusterConfig::FixedZ::dimensions_for_screen_size builds an AspectRatio from the render target size and .expect()s it (crates/bevy_light/src/cluster/mod.rs:318). A zero width or height makes AspectRatio::try_from_pixels fail with AspectRatioError::Zero, and the expect turns that into this panic during light clustering.

Source

Thrown at crates/bevy_light/src/cluster/mod.rs:320

            total: 4096,
            z_slices: 24,
            z_config: ClusterZConfig::default(),
            dynamic_resizing: true,
        }
    }
}

impl ClusterConfig {
    fn dimensions_for_screen_size(&self, screen_size: UVec2) -> UVec3 {
        match &self {
            ClusterConfig::None => UVec3::ZERO,
            ClusterConfig::Single => UVec3::ONE,
            ClusterConfig::XYZ { dimensions, .. } => *dimensions,
            ClusterConfig::FixedZ {
                total, z_slices, ..
            } => {
                let aspect_ratio: f32 = AspectRatio::try_from_pixels(screen_size.x, screen_size.y)
                    .expect("Failed to calculate aspect ratio for Cluster: screen dimensions must be positive, non-zero values")
                    .ratio();
                let mut z_slices = *z_slices;
                if *total < z_slices {
                    warn!("ClusterConfig has more z-slices than total clusters!");
                    z_slices = *total;
                }
                let per_layer = *total as f32 / z_slices as f32;

                let y = f32::sqrt(per_layer / aspect_ratio);

                let mut x = (y * aspect_ratio) as u32;
                let mut y = y as u32;

                // check extremes
                if x == 0 {
                    x = 1;
                    y = per_layer as u32;
                }

View on GitHub (pinned to 4805ca792c)

Solutions

  1. Prevent zero-sized windows/camera targets (clamp resizes, pause rendering while minimized).
  2. Use ClusterConfig::None or ClusterConfig::Single for cameras whose targets may legitimately be zero-sized.
  3. Update Bevy — zero-size clustering handling has been patched across releases, so a newer minor may already contain the fix.

Example fix

// before: minimized window (0x0) + ClusterConfig::FixedZ -> panic in light clustering

// after: guard zero-size frames in your camera/window update logic
let size = window.physical_size();
if size.x == 0 || size.y == 0 {
    return; // skip work while there is no drawable area
}
Defensive patterns

Strategy: validation

Validate before calling

use bevy_window::Window;

fn screen_size_valid(window: &Window) -> bool {
    window.physical_size().x > 0 && window.physical_size().y > 0
}

// in systems that create/resize cameras or react to window changes:
if !screen_size_valid(&window) {
    return; // skip frame: zero-size target would panic FixedZ clustering
}

Prevention

When it happens

Trigger: Forward-clustered lighting (ClusterConfig::FixedZ) running while a camera's screen/target size is (0, 0) — a minimized window, a zero-sized surface during resize or recreation, or a camera targeting a zero-sized image.

Common situations: Minimizing the window during play; WMs that briefly resize to zero during tiling transitions; secondary cameras on not-yet-sized render targets; headless or surface-recreation paths.

Related errors


AI-assisted analysis of bevyengine/bevy@4805ca792c (2026-08-20). Data as JSON: /api/errors/93d3abed95f8b0fd. Report an issue: GitHub.