{"record":{"id":"5e0aaac6a350111c","repo":"slint-ui/slint","slug":"editorsession-must-have-at-least-one-preview","errorCode":null,"errorMessage":"EditorSession must have at least one preview","messagePattern":"EditorSession must have at least one preview","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/editor-preview/editor_session.rs","lineNumber":49,"sourceCode":"    pub to_show: Option<PreviewComponent>,\n}\n\n/// The documents currently being edited, together with the state the preview\n/// needs to follow along.\npub struct EditorSession {\n    pub document_cache: crate::DocumentCache,\n    pub preview_config: PreviewConfig,\n    /// File currently open in the editor\n    pub open_urls: HashSet<lsp_types::Url>,\n    pub previews: Vec<PreviewConnection>,\n    /// Files to recompile after all other operations are done\n    /// (i.e. recompilations triggered by updates to unopened files)\n    pub pending_recompile: HashSet<lsp_types::Url>,\n}\n\nimpl EditorSession {\n    pub fn primary_preview(&self) -> &PreviewConnection {\n        self.previews.first().expect(\"EditorSession must have at least one preview\")\n    }\n\n    pub fn primary_preview_mut(&mut self) -> &mut PreviewConnection {\n        self.previews.first_mut().expect(\"EditorSession must have at least one preview\")\n    }\n\n    pub fn preview(&self, preview_index: usize) -> Option<&PreviewConnection> {\n        let preview = self.previews.get(preview_index);\n        if preview.is_none() {\n            tracing::warn!(\n                \"Preview index {preview_index} is out of bounds for {} previews\",\n                self.previews.len()\n            );\n        }\n        preview\n    }\n\n    pub fn preview_mut(&mut self, preview_index: usize) -> Option<&mut PreviewConnection> {","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/slint-ui/slint/blob/bb937076de3f7919766c1f25e2e969367cf77e9a/internal/editor-preview/editor_session.rs#L31-L67","documentation":"`primary_preview()` returns the first element of `EditorSession::previews` and panics via `expect` when the list is empty. The invariant is that an `EditorSession` always has at least one live preview connection (the editor always opens at least one preview). A session created or drained without a preview violates construction invariants.","triggerScenarios":"Calling `session.primary_preview()` on an `EditorSession` whose `previews` Vec is empty — e.g. the session was constructed via `Default`/`EditorSession::new` without registering a preview connection, or the only preview was removed/closed beforehand.","commonSituations":"Hit when tooling embeds the editor-preview crate directly (tests, custom preview harnesses) and creates a session without going through the normal editor startup that spawns a preview; also after code changes that allow closing the last preview.","solutions":["Ensure the preview connection is registered before using the session (go through the normal editor-preview startup path)","Use `previews.first()` / `session.preview(0)` and handle `None` instead of `primary_preview()`","In tests, construct the session via the API that seeds at least one `PreviewConnection`","Report upstream if the main editor itself closed the last preview and still calls this"],"exampleFix":"// before\nlet preview = session.primary_preview();\n// after\nlet preview = session.previews.first()\n    .ok_or_else(|| anyhow::anyhow!(\"no preview connection available\"))?;","handlingStrategy":"type-guard","validationCode":"if session.previews.is_empty() { /* cannot use primary_preview */ }","typeGuard":"fn has_preview(s: &EditorSession) -> bool { !s.previews.is_empty() }","tryCatchPattern":null,"preventionTips":["Construct EditorSession only through APIs that seed a preview","Prefer `preview(index) -> Option<&PreviewConnection>` over primary accessors","Never close the last preview while the session lives; assert non-empty in session teardown tests"],"tags":["lsp","preview","rust","panic"],"backgroundTag":"empty-required-field","analyzedSha":"bb937076de3f7919766c1f25e2e969367cf77e9a","analyzedAt":"2026-09-16T01:37:20.251Z","contentChangedAt":"2026-09-16T01:37:20.251Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}