iced-rs/iced · error
Line layout should be cached
Error message
Line layout should be cached
What it means
cosmic-text computes line layouts lazily: a BufferLine only carries a layout after shaping ran (shape_until_scroll / shape_as_needed, invoked from Editor::update/overwrite/perform). Editor::highlight (editor.rs:821) walks the visible window line by line and asserts line.layout_opt() is Some; if any line in [scroll.line, last_visible_line] was never shaped, expect("Line layout should be cached") fires.
Solutions
- Run the editor lifecycle in order: with_text/update (which shapes) before highlight, mirroring iced's text_editor widget
- Pass identical bounds to update and the subsequent highlight so the visible window matches what was shaped
- For very large buffers, ensure shaping completed past the visible region before highlighting
- If it persists with stock widgets, upgrade iced: visible-window/shaping order bugs were fixed across releases
Example fix
// before - highlight before any shaping ran let mut editor = Editor::with_text(text); editor.highlight(font, &mut highlighter, fmt); // after - shape first, then highlight editor.update(bounds, font, size, line_height, wrapping, alignment, hint_factor, &mut highlighter); editor.highlight(font, &mut highlighter, fmt);
Defensive patterns
Strategy: validation
Validate before calling
// before triggering highlight, confirm the visible lines are shaped
let shaped = editor.buffer().lines.iter().all(|l| l.layout_opt().is_some());
if !shaped {
// run the update/shaping pass first (correct bounds, font, size)
editor.update(bounds, font, size, line_height, wrapping, alignment, hint, &mut highlighter);
}
editor.highlight(font, &mut highlighter, fmt); Prevention
- Always order the editor lifecycle: with_text/update (shapes) before highlight
- Pass the same bounds to update and highlight so the visible window matches what was shaped
- For very large documents, ensure shaping completes past the visible region
- Model custom text widgets on iced's text_editor widget ordering
When it happens
Trigger: Calling highlight before any shaping pass ran; passing bounds to update that are smaller than what highlight later assumes, so the visible window reaches unshaped lines; scrolling deep into a huge document whose shaping was cut short (shape_until_scroll with false).
Common situations: Custom widgets driving editor::Editor with a hand-ordered lifecycle (highlight before update); resizing the editor between update and highlight; loading very large files where shaping has not caught up with the scroll position.
Related errors
- Write font system
- Editor cannot have multiple strong references
- Editor should always be initialized
- Read font system
- Write font system
AI-assisted analysis of iced-rs/iced@3de451447b (2026-08-17).
Data as JSON: /api/errors/90b0ae120b7f3ab5.
Report an issue: GitHub.
Appendix: source
Thrown at graphics/src/text/editor.rs:821
highlighter: &mut H,
format_highlight: impl Fn(&H::Highlight) -> highlighter::Format<Self::Font>,
) {
let internal = self.internal();
let buffer = buffer_from_editor(&internal.editor);
let scroll = buffer.scroll();
let mut window = (internal.bounds.height * internal.hint_factor
/ buffer.metrics().line_height)
.ceil() as i32;
let last_visible_line = buffer.lines[scroll.line..]
.iter()
.enumerate()
.find_map(|(i, line)| {
let visible_lines = line
.layout_opt()
.as_ref()
.expect("Line layout should be cached")
.len() as i32;
if window > visible_lines {
window -= visible_lines;
None
} else {
Some(scroll.line + i)
}
})
.unwrap_or(buffer.lines.len().saturating_sub(1));
let current_line = highlighter.current_line();
if current_line > last_visible_line {
return;
}
let editor = self.0.take().expect("Editor should always be initialized");View on GitHub (pinned to 3de451447b)