{"record":{"id":"7d43520c1927a758","repo":"iced-rs/iced","slug":"editor-should-always-be-initialized","errorCode":null,"errorMessage":"Editor should always be initialized","messagePattern":"Editor should always be initialized","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graphics/src/text/editor.rs","lineNumber":839,"sourceCode":"                    .expect(\"Line layout should be cached\")\n                    .len() as i32;\n\n                if window > visible_lines {\n                    window -= visible_lines;\n                    None\n                } else {\n                    Some(scroll.line + i)\n                }\n            })\n            .unwrap_or(buffer.lines.len().saturating_sub(1));\n\n        let current_line = highlighter.current_line();\n\n        if current_line > last_visible_line {\n            return;\n        }\n\n        let editor = self.0.take().expect(\"Editor should always be initialized\");\n\n        let mut internal =\n            Arc::try_unwrap(editor).expect(\"Editor cannot have multiple strong references\");\n\n        let mut font_system = text::font_system().write().expect(\"Write font system\");\n\n        let attributes = text::to_attributes(font);\n\n        for line in &mut buffer_mut_from_editor(&mut internal.editor).lines\n            [current_line..=last_visible_line]\n        {\n            let mut list = cosmic_text::AttrsList::new(&attributes);\n\n            for (range, highlight) in highlighter.highlight_line(line.text()) {\n                let format = format_highlight(&highlight);\n\n                if format.color.is_some() || format.font.is_some() {\n                    list.add_span(","sourceCodeStart":821,"sourceCodeEnd":857,"githubUrl":"https://github.com/iced-rs/iced/blob/3de451447bd28217bb535632867550908e29d5d0/graphics/src/text/editor.rs#L821-L857","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before - keep using an editor after a caught panic\nif std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| editor.perform(action))).is_err() {\n    editor.highlight(font, &mut hl, fmt); // panics: internals left empty\n}\n\n// after - rebuild the editor after any panic\nif std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| editor.perform(action))).is_err() {\n    editor = Editor::with_text(&contents); // fresh internals\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let ok = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    editor.perform(action)\n}));\nif ok.is_err() {\n    // internals were take()n and not restored: rebuild instead of reusing\n    editor = Editor::with_text(&contents);\n}","preventionTips":["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"],"tags":["rust","iced","editor","panic-recovery","option"],"backgroundTag":"option-unexpected-none","analyzedSha":"3de451447bd28217bb535632867550908e29d5d0","analyzedAt":"2026-08-17T10:40:26.997Z","contentChangedAt":"2026-08-17T10:40:26.997Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}