{"record":{"id":"874ee2aa68d03c50","repo":"zellij-org/zellij","slug":"active-tab-does-not-exist","errorCode":null,"errorMessage":"active tab {} does not exist","messagePattern":"active tab (.+?) does not exist","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"zellij-server/src/screen.rs","lineNumber":4280,"sourceCode":"        Ok(())\n    }\n\n    /// Returns a mutable reference to this [`Screen`]'s tabs.\n    pub fn get_tabs_mut(&mut self) -> &mut BTreeMap<usize, Tab> {\n        &mut self.tabs\n    }\n\n    pub fn get_tabs(&self) -> &BTreeMap<usize, Tab> {\n        &self.tabs\n    }\n\n    /// Returns an immutable reference to this [`Screen`]'s active [`Tab`].\n    pub fn get_active_tab(&self, client_id: ClientId) -> Result<&Tab> {\n        match self.active_tab_ids.get(&client_id) {\n            Some(tab) => self\n                .tabs\n                .get(tab)\n                .ok_or_else(|| anyhow!(\"active tab {} does not exist\", tab)),\n            None => Err(anyhow!(\"active tab not found for client {:?}\", client_id)),\n        }\n    }\n\n    pub fn get_client_input_mode(&self, client_id: ClientId) -> Option<InputMode> {\n        self.get_active_tab(client_id)\n            .ok()\n            .and_then(|tab| tab.get_client_input_mode(client_id))\n    }\n\n    pub fn get_first_client_id(&self) -> Option<ClientId> {\n        self.active_tab_ids.keys().next().copied()\n    }\n\n    /// Returns an immutable reference to this [`Screen`]'s previous active [`Tab`].\n    /// Consumes the last entry in tab history.\n    pub fn get_previous_tab(&mut self, client_id: ClientId) -> Result<Option<&Tab>> {\n        Ok(","sourceCodeStart":4262,"sourceCodeEnd":4298,"githubUrl":"https://github.com/zellij-org/zellij/blob/98a0837077492d53dd252ab30bc3e43e41e504f4/zellij-server/src/screen.rs#L4262-L4298","documentation":"Screen::get_active_tab maps a client's entry in active_tab_ids to a Tab in the tabs BTreeMap. This error means the client's recorded active tab id has no corresponding Tab — the two structures are out of sync, e.g. the tab was closed without updating active_tab_ids for that client.","triggerScenarios":"Any caller of get_active_tab (rendering, input-mode queries, focus operations) after the tab referenced by active_tab_ids[client_id] was removed from self.tabs — close-tab paths that skip updating the client's active pointer, or a client reconnecting with stale state.","commonSituations":"Closing the active tab of a client in multi-client sessions; plugin actions closing arbitrary tabs; resurrection/session-restore rehydrating clients with stale active tab ids.","solutions":["Update or clear the client's active tab pointer when closing tabs (set_active_tab / the tab-close handlers) so active_tab_ids never outlives the tab","Callers should handle the Err and pick a fallback tab (e.g. first key of self.tabs) instead of crashing","Reproduce and report upstream if a stock keybinding flow leaves the desync behind"],"exampleFix":"// before\nlet tab = screen.get_active_tab(client_id)?;\n\n// after\nlet tab = screen\n    .get_active_tab(client_id)\n    .or_else(|_| screen.get_tabs().values().next().context(\"no tabs exist\"))?;","handlingStrategy":"fallback","validationCode":null,"typeGuard":"fn client_tab_alive(active_tab_ids: &HashMap<ClientId, usize>, tabs: &BTreeMap<usize, Tab>, client: ClientId) -> bool {\n    active_tab_ids.get(&client).map_or(false, |id| tabs.contains_key(id))\n}","tryCatchPattern":"let tab = screen\n    .get_active_tab(client_id)\n    .or_else(|_| screen.get_tabs().values().next().context(\"no tabs exist\"))?;","preventionTips":["Always update active_tab_ids when closing a client's active tab","Callers of get_active_tab should fall back to the first remaining tab on Err"],"tags":["tabs","client","state-desync","focus","screen"],"backgroundTag":null,"analyzedSha":"98a0837077492d53dd252ab30bc3e43e41e504f4","analyzedAt":"2026-08-16T13:02:01.396Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}