zellij-org/zellij · warning · anyhow::Error
No tabs left, cannot move clients: {:?} from closed tab
Error message
No tabs left, cannot move clients: {:?} from closed tab What it means
move_clients_from_closed_tab relocates clients off a just-closed tab onto the first remaining tab. When self.tabs is empty (the closed tab was the last one), there is nowhere to move them; zellij logs this non-fatal error and returns Ok(()) — the session is ending anyway.
Source
Thrown at zellij-server/src/screen.rs:1820
.find(|t| t.position == position)
.map(|t| t.id)
}
/// Gets the display position of the tab with the given ID.
///
/// Use this to convert ID → position for user-facing operations.
fn get_tab_position_by_id(&self, id: usize) -> Option<usize> {
self.tabs.get(&id).map(|t| t.position)
}
fn move_clients_from_closed_tab(
&mut self,
client_ids_and_mode_infos: Vec<(ClientId, ModeInfo)>,
) -> Result<()> {
let err_context = || "failed to move clients from closed tab".to_string();
if self.tabs.is_empty() {
Err::<(), _>(anyhow!(
"No tabs left, cannot move clients: {:?} from closed tab",
client_ids_and_mode_infos
))
.with_context(err_context)
.non_fatal();
return Ok(());
}
let first_tab_index = *self
.tabs
.keys()
.next()
.context("screen contained no tabs")
.with_context(err_context)?;
for (client_id, client_mode_info) in client_ids_and_mode_infos {
let client_tab_history = self.tab_history.entry(client_id).or_insert_with(Vec::new);
if let Some(client_previous_tab) = client_tab_history.pop() {
if let Some(client_active_tab) = self.tabs.get_mut(&client_previous_tab) {View on GitHub (pinned to 98a0837077)
Solutions
- No fix needed — expected during session teardown and explicitly non-fatal
- If it fires outside shutdown, check for code paths closing tabs twice (double close events)
- Plugin authors: prefer the standard close-tab actions over directly manipulating tab state
Defensive patterns
Strategy: fallback
Type guard
fn has_remaining_tabs(screen: &Screen) -> bool {
!screen.get_tabs().is_empty()
} Try / catch
if self.tabs.is_empty() {
// non_fatal log + Ok(()) — session is ending; nothing to relocate
return Ok(());
} Prevention
- Treat as expected during last-tab close / session exit
- Guard custom flows that close tabs against double-close events
When it happens
Trigger: Closing the final tab of a session (all clients disconnect) while clients still hold ModeInfo for that tab; races where tab bookkeeping empties before client state is drained.
Common situations: Normal exit-by-last-tab-close, `zellij kill-session`, or kill-all-tabs keybindings; plugin-driven tab closing that removes the last tab.
Related errors
- found no sender to send plugin instruction to
- Tab index {:?} not found
- Failed to get running plugin
- Failed to convert to protobuf: {:?}
- Failed to serialized plugin ids: {}
AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16).
Data as JSON: /api/errors/17384d6587df7a76.
Report an issue: GitHub.