{"record":{"id":"61ff34407af25061","repo":"FyroxEngine/Fyrox","slug":"missing-hole-mask-texture","errorCode":null,"errorMessage":"Missing hole mask texture","messagePattern":"Missing hole mask texture","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fyrox-impl/src/scene/terrain/mod.rs","lineNumber":2236,"sourceCode":"            BrushTarget::LayerMask { .. } => TerrainTextureKind::Mask,\n            BrushTarget::HoleMask => TerrainTextureKind::Mask,\n        };\n        let resources: FxHashMap<Vector2<i32>, TextureResource> = match target {\n            BrushTarget::HeightMap => self\n                .chunks_ref()\n                .iter()\n                .map(|c| (c.grid_position(), c.heightmap().clone()))\n                .collect(),\n            BrushTarget::HoleMask => self\n                .chunks_ref()\n                .iter()\n                .map(|c| {\n                    (\n                        c.grid_position(),\n                        c.hole_mask\n                            .as_ref()\n                            .cloned()\n                            .expect(\"Missing hole mask texture\"),\n                    )\n                })\n                .collect(),\n            BrushTarget::LayerMask { layer } => self\n                .chunks_ref()\n                .iter()\n                .map(|c| (c.grid_position(), c.layer_masks[layer].clone()))\n                .collect(),\n        };\n        TerrainTextureData {\n            chunk_size,\n            kind,\n            resources,\n        }\n    }\n    /// Modify the given BrushStroke so that it is using the given Brush and it is modifying this terrain.\n    /// The BrushStroke will now hold references to the textures of this terrain for the target of the given brush,\n    /// and so the stroke should not be used with other terrains until the stroke is finished.","sourceCodeStart":2218,"sourceCodeEnd":2254,"githubUrl":"https://github.com/FyroxEngine/Fyrox/blob/76c91aad8eca488ce527b1af707be8b3b24ad72d/fyrox-impl/src/scene/terrain/mod.rs#L2218-L2254","documentation":"When painting a terrain's hole mask brush target, the terrain collects each chunk's hole_mask texture and calls expect on it, panicking if any chunk has no hole mask assigned. Invariant: using the hole-mask brush requires every chunk to have a hole mask texture.","triggerScenarios":"Applying a brush with BrushTarget::HoleMask while at least one terrain chunk was created without a hole_mask texture (e.g. chunks built via code or older saved scenes predating hole masks).","commonSituations":"Programmatically constructing Terrain chunks at runtime without assigning hole_mask; loading terrains saved by older engine versions where the field did not exist; editing hole masks in the editor after regenerating chunks.","solutions":["Assign a hole mask texture to every chunk before using the hole-mask brush (Chunk::set_hole_mask with a valid texture handle).","Iterate chunks and guard: if chunk.hole_mask().is_none(), create/assign a default mask before invoking the brush.","Re-save the terrain in the current editor version so the hole masks are serialized with the scene."],"exampleFix":"// before\nfor chunk in terrain.chunks_ref() { /* no hole mask set */ }\nbrush.apply(&mut terrain, ...); // panics\n// after\nfor mut chunk in terrain.chunks_mut() {\n    if chunk.hole_mask().is_none() {\n        chunk.set_hole_mask(default_mask_texture.clone());\n    }\n}\nbrush.apply(&mut terrain, ...);","handlingStrategy":"validation","validationCode":"if terrain.chunks_ref().iter().any(|c| c.hole_mask().is_none()) {\n    // set hole masks before using BrushTarget::HoleMask\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always assign a hole mask texture to terrain chunks before painting holes","Re-save legacy terrains in the current engine version"],"tags":["terrain","texture","panic","fyrox"],"backgroundTag":"missing-required-config","analyzedSha":"76c91aad8eca488ce527b1af707be8b3b24ad72d","analyzedAt":"2026-09-10T16:04:01.633Z","contentChangedAt":"2026-09-10T16:04:01.633Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}