FyroxEngine/Fyrox · error
A brush painting message was not sent.
Error message
A brush painting message was not sent. {error:?} What it means
Terrain brush painting communicates with a background worker thread via a channel; on_send_failure is the unwrap_or_else handler invoked when sending a BrushThreadMessage fails (receiver dropped). It logs that the painting command was not delivered.
Solutions
- Ensure the terrain and its brush thread outlive all brush painting calls (don't drop/destroy terrain mid-stroke).
- Check earlier logs for a brush worker panic that terminated the receiving thread.
- Guard brush UI/input handling so strokes end (finish_stroke) before terrain teardown.
Defensive patterns
Strategy: fallback
Validate before calling
// Before painting, verify the terrain handle still points to a live node with an active brush:
if let Some(terrain) = scene.graph.try_get(terrain_handle).ok() {
terrain.paint(brush, stroke);
} Prevention
- Never destroy terrain nodes while a brush stroke is in progress.
- Finish strokes before scene shutdown/teardown.
- Watch logs for earlier brush-thread panics that kill the worker.
When it happens
Trigger: BrushStroke operations (apply/commit/reset) calling message send on the brush thread channel after the worker thread has exited, producing SendError<BrushThreadMessage> handled by on_send_failure.
Common situations: Terrain destroyed or brush worker shut down while painting is still in progress; editor shutdown racing an in-flight stroke; a panic previously killed the worker thread.
Related errors
- Terrain brush operation dropped due to sanity limit
- Invalid brush stroke. Holes are not enabled on terrain.
- Setting latest value of missing element
- Invalid pixel position
- Invalid texture kind.
AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10).
Data as JSON: /api/errors/572327e08eba208a.
Report an issue: GitHub.
Appendix: source
Thrown at fyrox-impl/src/scene/terrain/brushstroke/mod.rs:228
}
/// Draw a pixel using the brush that was set in the most recent call to [BrushSender::start_stroke].
#[inline]
pub fn draw_pixel(&self, position: Vector2<i32>, alpha: f32, value: f32) {
if alpha == 0.0 {
return;
}
self.0
.send(BrushThreadMessage::Pixel(BrushPixelMessage {
position,
alpha,
value,
}))
.unwrap_or_else(on_send_failure);
}
}
fn on_send_failure(error: SendError<BrushThreadMessage>) {
Log::err(format!("A brush painting message was not sent. {error:?}"));
}
/// Type for a callback that delivers the original data of textures that have been modified
/// by the brush so that changes might be undone.
pub type UndoChunkHandler = dyn FnMut(UndoData) + Send;
/// A record of original data data for chunks that have been modified by a brushstroke.
pub struct UndoData {
/// The handle of the terrain being edited
pub node: Handle<Node>,
/// The data of the chunks as they were before the brushstroke.
pub chunks: Vec<ChunkData>,
/// The kind of data within the terrain that is being edited.
pub target: BrushTarget,
}
#[derive(Default)]
/// Data for an in-progress terrain painting operationView on GitHub (pinned to 76c91aad8e)