{"record":{"id":"ade439fb2e73b5ac","repo":"bevyengine/bevy","slug":"point-cloud-must-contain-at-least-one-point-for-aa-ade439","errorCode":null,"errorMessage":"point cloud must contain at least one point for Aabb3d construction","messagePattern":"point cloud must contain at least one point for Aabb3d construction","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/bevy_math/src/bounding/bounded3d/mod.rs","lineNumber":101,"sourceCode":"    /// Computes the smallest [`Aabb3d`] containing the given set of points,\n    /// transformed by the rotation and translation of the given isometry.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the given set of points is empty.\n    #[inline]\n    pub fn from_point_cloud(\n        isometry: impl Into<Isometry3d>,\n        points: impl Iterator<Item = impl Into<Vec3A>>,\n    ) -> Aabb3d {\n        let isometry = isometry.into();\n\n        // Transform all points by rotation\n        let mut iter = points.map(|point| isometry.rotation * point.into());\n\n        let first = iter\n            .next()\n            .expect(\"point cloud must contain at least one point for Aabb3d construction\");\n\n        let (min, max) = iter.fold((first, first), |(prev_min, prev_max), point| {\n            (point.min(prev_min), point.max(prev_max))\n        });\n\n        Aabb3d {\n            min: min + isometry.translation,\n            max: max + isometry.translation,\n        }\n    }\n\n    /// Computes the smallest [`BoundingSphere`] containing this [`Aabb3d`].\n    #[inline]\n    pub fn bounding_sphere(&self) -> BoundingSphere {\n        let radius = self.min.distance(self.max) / 2.0;\n        BoundingSphere::new(self.center(), radius)\n    }\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_math/src/bounding/bounded3d/mod.rs#L83-L119","documentation":"Aabb3d::from_point_cloud panics via .expect when the input iterator yields no items (crates/bevy_math/src/bounding/bounded3d/mod.rs:101) — the min/max fold needs a first point to seed from. It is a panic by design, so empty iterators must be filtered before the call.","triggerScenarios":"Calling Aabb3d::from_point_cloud(isometry, iter) where iter is empty — e.g. an iterator over an empty vertex buffer, an emptied query, or a fully-filtered collection.","commonSituations":"Mesh bounds computed during async loading before vertex data exists; iterators consumed earlier so they yield nothing on the second pass; entity queries matching no entities.","solutions":["Materialize and check the iterator is non-empty before calling from_point_cloud.","Skip or early-return for empty sets instead of computing bounds.","Be careful not to consume an iterator before passing it (an already-drained iterator is empty)."],"exampleFix":"// before\nlet aabb = Aabb3d::from_point_cloud(iso, iter); // panics on empty iterator\n\n// after\nlet collected: Vec<_> = iter.collect();\nif collected.is_empty() {\n    return;\n}\nlet aabb = Aabb3d::from_point_cloud(iso, collected.into_iter());","handlingStrategy":"validation","validationCode":"fn point_cloud_aabb3d(\n    iso: impl Into<Isometry3d>,\n    points: impl Iterator<Item = impl Into<Vec3A>>,\n) -> Option<Aabb3d> {\n    let points: Vec<_> = points.collect();\n    if points.is_empty() {\n        return None;\n    }\n    Some(Aabb3d::from_point_cloud(iso, points.into_iter()))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Materialize iterators and check emptiness before computing bounds.","Do not pass an iterator that may already have been consumed.","Return Option<Aabb3d> from bounds helpers so empty sets are handled explicitly."],"tags":["bevy","math","bounding-volume","aabb","panic","empty-iterator"],"backgroundTag":"empty-slice-panic","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}