iced-rs/iced · error
Editor should always be initialized
Error message
Editor should always be initialized
What it means
Editor stores its internals as Option<Arc<Internal>>. The field starts as Some (Editor::default builds an Internal), and every mutating helper take()s it and puts it back at the end (see with_internal_mut at editor.rs:63-78). expect("Editor should always be initialized") at editor.rs:839 therefore fires only when a previous mutating call panicked midway - after the take() but before the value was restored - leaving the Option empty.
Solutions
- Fix the FIRST panic (often "Write font system" or "Line layout should be cached" earlier in the same log); this expect is only the follow-up
- Recreate the editor state after any caught panic: rebuild the widget tree or re-run with_text instead of reusing the editor
- Do not swallow panics from editor methods and continue using the same instance
- Upgrade iced so the original panic path is fixed
Example fix
// before - keep using an editor after a caught panic
if std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| editor.perform(action))).is_err() {
editor.highlight(font, &mut hl, fmt); // panics: internals left empty
}
// after - rebuild the editor after any panic
if std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| editor.perform(action))).is_err() {
editor = Editor::with_text(&contents); // fresh internals
} Defensive patterns
Strategy: fallback
Try / catch
let ok = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
editor.perform(action)
}));
if ok.is_err() {
// internals were take()n and not restored: rebuild instead of reusing
editor = Editor::with_text(&contents);
} Prevention
- Fix the first panic; this expect only fires as follow-up after a mid-flight panic
- Never reuse an editor (or widget tree) after a caught panic: rebuild it
- Do not call editor methods re-entrantly from inside editor callbacks
- Log panics with backtraces so the first failure is diagnosable
When it happens
Trigger: A second call to highlight/perform/update/overwrite after an earlier panic inside those methods (e.g. a "Write font system" or "Line layout should be cached" panic) left self.0 = None; re-entrant use of the same editor while a take() is in flight.
Common situations: Apps that catch panics with catch_unwind and keep running on the same widget state; background tasks re-driving an editor after a text panic; the follow-up crash in logs after a first editor panic.
Related errors
- Editor cannot have multiple strong references
- Line layout should be cached
- Write font system
- Caches must not be empty
- Create color
AI-assisted analysis of iced-rs/iced@3de451447b (2026-08-17).
Data as JSON: /api/errors/7d43520c1927a758.
Report an issue: GitHub.
Appendix: source
Thrown at graphics/src/text/editor.rs:839
.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");
let mut internal =
Arc::try_unwrap(editor).expect("Editor cannot have multiple strong references");
let mut font_system = text::font_system().write().expect("Write font system");
let attributes = text::to_attributes(font);
for line in &mut buffer_mut_from_editor(&mut internal.editor).lines
[current_line..=last_visible_line]
{
let mut list = cosmic_text::AttrsList::new(&attributes);
for (range, highlight) in highlighter.highlight_line(line.text()) {
let format = format_highlight(&highlight);
if format.color.is_some() || format.font.is_some() {
list.add_span(View on GitHub (pinned to 3de451447b)