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

  1. Retry the split once after a tick - usually a transient race that self-resolves
  2. Guard before splitting: if #tab:panes() == 0 then return end
  3. Resolve the target window/tab freshly (wezterm.gui.get_window_by_id(...) :active_tab()) before each split
  4. 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

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


AI-assisted analysis of wezterm/wezterm@3ff7522b96 (2026-08-20). Data as JSON: /api/errors/7b1c6544632a9f55. Report an issue: GitHub.