{"record":{"id":"7b1c6544632a9f55","repo":"wezterm/wezterm","slug":"tab-to-have-a-pane","errorCode":null,"errorMessage":"tab to have a pane","messagePattern":"tab to have a pane","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"wezterm-gui/src/spawn.rs","lineNumber":104,"sourceCode":"            if let Some(cwd) = &spawn.cwd {\n                builder.cwd(cwd);\n            }\n            Some(builder)\n        }\n    };\n\n    let workspace = mux.active_workspace().clone();\n\n    match spawn_where {\n        SpawnWhere::SplitPane(direction) => {\n            let src_window_id = match src_window_id {\n                Some(id) => id,\n                None => anyhow::bail!(\"no src window when splitting a pane?\"),\n            };\n            if let Some(tab) = mux.get_active_tab_for_window(src_window_id) {\n                let pane = tab\n                    .get_active_pane()\n                    .ok_or_else(|| anyhow!(\"tab to have a pane\"))?;\n\n                log::trace!(\"doing split_pane\");\n                let (pane, _size) = mux\n                    .split_pane(\n                        // tab.tab_id(),\n                        pane.pane_id(),\n                        direction,\n                        SplitSource::Spawn {\n                            command: cmd_builder,\n                            command_dir: cwd,\n                        },\n                        spawn.domain,\n                    )\n                    .await\n                    .context(\"split_pane\")?;\n                pane.set_config(term_config);\n            } else {\n                bail!(\"there is no active tab while splitting pane!?\");","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/wezterm/wezterm/blob/3ff7522b9617ec920f7fbdb22b57e93d42d93ee9/wezterm-gui/src/spawn.rs#L86-L122","documentation":"Handling SpawnWhere::SplitPane, wezterm looks up the source window's active tab and requires tab.get_active_pane() to yield a pane to split. 'tab to have a pane' fires when the tab exists but reports no active pane - its panes were already removed (last process exited, tab tearing down) at the instant of the split.","triggerScenarios":"A SplitPane key binding or Lua action landing exactly as the last pane's process exits; issuing splits in a loop against a window that is closing; racing pane exit with mux.split_pane preparation.","commonSituations":"Split hotkeys during heavy churn (batch process exit, window close); automation scripts firing splits against stale window handles; flaky and timing-dependent.","solutions":["Retry the split once after a tick - usually a transient race that self-resolves","Guard before splitting: if #tab:panes() == 0 then return end","Resolve the target window/tab freshly (wezterm.gui.get_window_by_id(...) :active_tab()) before each split","If deterministically reproducible, upgrade wezterm and report it - deterministic empty tabs at split time are a bug"],"exampleFix":"-- before\nwezterm.action.SplitPane { direction = 'Right' } -- may hit a closing tab\n\n-- after\nlocal tab = win:active_tab()\nif tab and #tab:panes() > 0 then\n  win:perform_action(wezterm.action.SplitPane { direction = 'Right' }, tab:active_pane())\nend","handlingStrategy":"validation","validationCode":"-- Lua: only split when the tab still has panes\nlocal tab = win:active_tab()\nif tab == nil or #tab:panes() == 0 then return end\nwin:perform_action(wezterm.action.SplitPane { direction = 'Right' }, tab:active_pane())","typeGuard":"local function tab_splittable(win)\n  local ok, tab = pcall(function() return win:active_tab() end)\n  return ok and tab ~= nil and #tab:panes() > 0\nend","tryCatchPattern":null,"preventionTips":["Resolve the window/tab freshly immediately before each split","In split loops, skip windows whose pane count is zero","Expect occasional races at pane exit and make splits idempotent/retryable"],"tags":["wezterm","split-pane","race-condition","pane-lifecycle"],"backgroundTag":"no-active-pane-in-tab","analyzedSha":"3ff7522b9617ec920f7fbdb22b57e93d42d93ee9","analyzedAt":"2026-08-20T04:47:31.434Z","contentChangedAt":"2026-08-20T04:47:31.434Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}