{"record":{"id":"0923172d5d27cb31","repo":"wezterm/wezterm","slug":"invalid-tab-id-092317","errorCode":null,"errorMessage":"Invalid tab id {}","messagePattern":"Invalid tab id (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mux/src/tmux_commands.rs","lineNumber":243,"sourceCode":"            Box::new(child),\n            Box::new(pane_pty),\n            Box::new(writer),\n            self.domain_id,\n            \"tmux pane\".to_string(),\n        )))\n    }\n\n    pub fn split_pane(\n        &self,\n        tab_id: TabId,\n        pane_id: PaneId,\n        remote_id: TmuxPaneId,\n        split_request: SplitRequest,\n    ) -> anyhow::Result<Arc<dyn Pane>> {\n        let mux = Mux::get();\n        let tab = match mux.get_tab(tab_id) {\n            Some(t) => t,\n            None => anyhow::bail!(\"Invalid tab id {}\", tab_id),\n        };\n\n        let pane_index = match tab\n            .iter_panes_ignoring_zoom()\n            .iter()\n            .find(|p| p.pane.pane_id() == pane_id)\n        {\n            Some(p) => p.index,\n            None => anyhow::bail!(\"invalid pane id {}\", pane_id),\n        };\n\n        let split_size = match tab.compute_split_size(pane_index, split_request) {\n            Some(s) => s,\n            None => anyhow::bail!(\"invalid pane index {}\", pane_index),\n        };\n\n        let window_id = match self.gui_tabs.lock().iter().find(|t| t.1.tab_id == tab_id) {\n            Some((_, tab)) => tab.tmux_window_id,","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/wezterm/wezterm/blob/9c04f79f86649f76a8c978ff4b674f60297a6ec9/mux/src/tmux_commands.rs#L225-L261","documentation":"TmuxDomainState::split_pane() (tmux_commands.rs:233) resolves a completed remote split into a local pane. First it looks up the local Tab by TabId in the Mux; when mux.get_tab(tab_id) returns None this bail fires. The Tab was removed — the tmux window was closed, the local window containing it was killed, or the mux is shutting down — while a split request for it was still in flight.","triggerScenarios":"A pending split promise resolving (WindowPaneChanged) after the user closed the window/tab in wezterm; mux.remove_tab running between the split request (Domain::split_pane captured tab_id) and the split_pane resolution call; GUI shutdown dropping tabs mid-operation.","commonSituations":"Closing a tmux-attached wezterm window immediately after issuing a split; rapid create/split/close sequences during scripting or UI automation.","solutions":["Check mux.get_tab(tab_id).is_some() before resolving the pending split; drop the split if the tab is gone","Abort pending_splits promises when a tab is removed so stale resolutions never run","On this error, discard the remote pane id (the tmux pane will be pruned by the next ListAllPanes sync)"],"exampleFix":"// before\nlet tab = match mux.get_tab(tab_id) {\n    Some(t) => t,\n    None => anyhow::bail!(\"Invalid tab id {}\", tab_id),\n};\n\n// after\nlet Some(tab) = mux.get_tab(tab_id) else {\n    log::debug!(\"tab {tab_id} gone; dropping split for pane {pane_id}\");\n    return Ok(None); // caller skips pane creation\n};","handlingStrategy":"validation","validationCode":"// Before resolving a pending split:\nif mux.get_tab(tab_id).is_none() {\n    // tab closed while split was in flight; drop the split\n    return Ok(None);\n}","typeGuard":"fn tab_alive(mux: &Mux, tab_id: TabId) -> bool {\n    mux.get_tab(tab_id).is_some()\n}","tryCatchPattern":"match state.split_pane(tab_id, pane_id, remote_id, req) {\n    Ok(pane) => Some(pane),\n    Err(e) if e.to_string().starts_with(\"Invalid tab id\") => {\n        None // stale split: let next ListAllPanes prune the remote pane\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Cancel pending_splits promises when their tab is removed (mux.remove_tab) so stale resolutions never fire","Capture tab_id at request time and re-validate at resolution time — assume tabs can die between","Treat stale-id errors during split resolution as droppable, not fatal"],"tags":["rust","wezterm","tmux","split-pane","tab-id","lifecycle"],"backgroundTag":"unknown-tab-id","analyzedSha":"9c04f79f86649f76a8c978ff4b674f60297a6ec9","analyzedAt":"2026-08-16T21:23:27.157Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}