{"record":{"id":"3b9369c7bb1f9875","repo":"sinelaw/fresh","slug":"active-window-present-bookmark-actions","errorCode":null,"errorMessage":"active window present","messagePattern":"active window present","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/app/bookmark_actions.rs","lineNumber":92,"sourceCode":"    ///\n    /// Stays on `impl Editor` because the body fires plugin hooks\n    /// (`apply_event_to_active_buffer`) and orchestrates cross-cutting\n    /// state (active-buffer switch, viewport recentering). Moving it\n    /// to `impl Window` waits for plugin-hook firing to be available\n    /// from `Window`.\n    pub(super) fn jump_to_bookmark(&mut self, key: char) {\n        let Some(bookmark) = self.active_window_mut().bookmarks.get(key) else {\n            self.set_status_message(t!(\"bookmark.not_set\", key = key).to_string());\n            return;\n        };\n\n        // Switch to the buffer if needed, or forget the bookmark if it's gone.\n        if bookmark.buffer_id != self.active_buffer() {\n            if self\n                .windows\n                .get(&self.active_window)\n                .map(|w| &w.buffers)\n                .expect(\"active window present\")\n                .contains_key(&bookmark.buffer_id)\n            {\n                self.set_active_buffer(bookmark.buffer_id);\n            } else {\n                self.set_status_message(t!(\"bookmark.buffer_gone\", key = key).to_string());\n                self.active_window_mut().bookmarks.remove(key);\n                return;\n            }\n        }\n\n        // Move cursor to bookmark position\n        let cursor = *self.active_cursors().primary();\n        let cursor_id = self.active_cursors().primary_id();\n        let state = self.active_state_mut();\n        let new_pos = bookmark.position.min(state.buffer.len());\n\n        let event = Event::MoveCursor {\n            cursor_id,","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/app/bookmark_actions.rs#L74-L110","documentation":"Panic from `.expect(\"active window present\")` in `jump_to_bookmark` (bookmark_actions.rs:92). Jumping to a bookmark whose buffer is not the active one checks whether that buffer still exists in the active window's buffer map; the expect asserts the active window exists. It panics if the bookmark action is dispatched while `self.active_window` does not resolve to an entry in `self.windows`.","triggerScenarios":"`handle_action` dispatches `jump_to_bookmark` for a bookmark with `buffer_id != self.active_buffer()`, and `self.windows.get(&self.active_window)` is None — active window closed/removed but `active_window` still references it.","commonSituations":"Invoking a bookmark jump via keybinding/command palette right after window teardown; stale bookmark registry pointing into a closed window; action queue replaying actions after window close.","solutions":["Replace the expect with a guard: if the active window is missing, either drop the action or show the 'buffer gone' status message.","Make window close always update `self.active_window` to a remaining window.","Prune bookmarks whose buffer/window no longer exists when windows close.","Add a regression test jumping to a bookmark after closing all windows."],"exampleFix":"// before\n.map(|w| &w.buffers)\n.expect(\"active window present\")\n.contains_key(&bookmark.buffer_id)\n// after\nlet Some(active) = self.windows.get(&self.active_window) else {\n    self.set_status_message(t!(\"bookmark.buffer_gone\", key = key).to_string());\n    return;\n};\nif active.buffers.contains_key(&bookmark.buffer_id) { ... }","handlingStrategy":"validation","validationCode":"if !self.windows.contains_key(&self.active_window) {\n    self.set_status_message(t!(\"bookmark.buffer_gone\", key = key).to_string());\n    return;\n}","typeGuard":"fn can_jump_to_bookmark(app: &App, bm: &Bookmark) -> bool {\n    app.windows.get(&app.active_window)\n        .map(|w| w.buffers.contains_key(&bm.buffer_id))\n        .unwrap_or(false)\n}","tryCatchPattern":"std::panic::catch_unwind(AssertUnwindSafe(|| self.jump_to_bookmark(key))).map_err(|_| self.set_status_message(\"bookmark unavailable\".into()));","preventionTips":["Validate bookmark targets (window + buffer exist) before executing jump actions.","Clean up bookmarks belonging to a window when that window is removed.","Prefer Option-based lookup with a status-message fallback over expect in user-action handlers.","Test bookmark jumps immediately after closing windows."],"tags":["rust","panic","bookmarks","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}