wezterm/wezterm · warning · anyhow::Error
tab to have a pane
Error message
tab to have a pane
What it means
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.
Source
Thrown at wezterm-gui/src/spawn.rs:104
if let Some(cwd) = &spawn.cwd {
builder.cwd(cwd);
}
Some(builder)
}
};
let workspace = mux.active_workspace().clone();
match spawn_where {
SpawnWhere::SplitPane(direction) => {
let src_window_id = match src_window_id {
Some(id) => id,
None => anyhow::bail!("no src window when splitting a pane?"),
};
if let Some(tab) = mux.get_active_tab_for_window(src_window_id) {
let pane = tab
.get_active_pane()
.ok_or_else(|| anyhow!("tab to have a pane"))?;
log::trace!("doing split_pane");
let (pane, _size) = mux
.split_pane(
// tab.tab_id(),
pane.pane_id(),
direction,
SplitSource::Spawn {
command: cmd_builder,
command_dir: cwd,
},
spawn.domain,
)
.await
.context("split_pane")?;
pane.set_config(term_config);
} else {
bail!("there is no active tab while splitting pane!?");View on GitHub (pinned to 3ff7522b96)
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
Example fix
-- before
wezterm.action.SplitPane { direction = 'Right' } -- may hit a closing tab
-- after
local tab = win:active_tab()
if tab and #tab:panes() > 0 then
win:perform_action(wezterm.action.SplitPane { direction = 'Right' }, tab:active_pane())
end Defensive patterns
Strategy: validation
Validate before calling
-- Lua: only split when the tab still has panes
local tab = win:active_tab()
if tab == nil or #tab:panes() == 0 then return end
win:perform_action(wezterm.action.SplitPane { direction = 'Right' }, tab:active_pane()) Type guard
local function tab_splittable(win) local ok, tab = pcall(function() return win:active_tab() end) return ok and tab ~= nil and #tab:panes() > 0 end
Prevention
- 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
When it happens
Trigger: 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.
Common situations: Split hotkeys during heavy churn (batch process exit, window close); automation scripts firing splits against stale window handles; flaky and timing-dependent.
Related errors
- invalid pane index {}
- unhandled type for {name}: {:#?}
- Gdi not compiled in
- NSPasteboard::generalPasteboard returned null
- Invalid tab id {}
AI-assisted analysis of wezterm/wezterm@3ff7522b96 (2026-08-20).
Data as JSON: /api/errors/7b1c6544632a9f55.
Report an issue: GitHub.