zellij-org/zellij · error · anyhow::Error

cannot respawn plugin panes

Error message

cannot respawn plugin panes

What it means

PtyBus::rerun_command_in_pane matches on PaneId: the Terminal arm spawns a fresh command, while the catch-all arm (PaneId::Plugin) immediately returns this error. Only terminal panes hold a PTY child process that can be re-run; plugin panes have no command to respawn.

Source

Thrown at zellij-server/src/pty.rs:1943

                self.task_handles.insert(id, terminal_bytes);
                self.pane_activity_flags.insert(id, activity_flag);
                if let Some(child_pid) = child_pid {
                    self.id_to_child_pid.insert(id, child_pid);
                    self.capture_initial_cwd(id, child_pid);
                }
                if let Some(originating_plugin) = self.originating_plugins.get(&id) {
                    self.bus
                        .senders
                        .send_to_plugin(PluginInstruction::Update(vec![(
                            Some(originating_plugin.plugin_id),
                            Some(originating_plugin.client_id),
                            Event::CommandPaneReRun(id, originating_plugin.context.clone()),
                        )]))
                        .with_context(err_context)?;
                }
                Ok(())
            },
            _ => Err(anyhow!("cannot respawn plugin panes")).with_context(err_context),
        }
    }
    pub fn populate_session_layout_metadata(
        &mut self,
        session_layout_metadata: &mut SessionLayoutMetadata,
    ) {
        let terminal_ids = session_layout_metadata.all_terminal_ids();
        let mut terminal_ids_to_commands: HashMap<u32, Vec<String>> = HashMap::new();
        let mut terminal_ids_to_cwds: HashMap<u32, PathBuf> = HashMap::new();

        let pids: Vec<_> = terminal_ids
            .iter()
            .filter_map(|id| self.id_to_child_pid.get(&id))
            .copied()
            .collect();
        let (pids_to_cwds, pids_to_cmds) = self
            .bus
            .os_input

View on GitHub (pinned to 98a0837077)

Solutions

  1. Check that the pane you target is a terminal pane, not a plugin pane (pane ids carry an is_plugin flag in the plugin API)
  2. To 'refresh' a plugin pane, use the plugin reload action (start_or_reload_plugin) instead of a command re-run
  3. If developing zellij, return a clearer message naming the PaneId::Plugin case in the catch-all arm

Example fix

// before (plugin pseudocode)
rerun_command_in_pane(pane_id); // pane_id may be a plugin pane -> Err

// after (plugin pseudocode)
if !pane_id.is_plugin {
    rerun_command_in_pane(pane_id);
} else {
    start_or_reload_plugin(&env, &plugin_url);
}
Defensive patterns

Strategy: type-guard

Type guard

fn rerunnable(pane_id: PaneId) -> bool {
    matches!(pane_id, PaneId::Terminal(_))
}

Try / catch

match pane_id {
    PaneId::Terminal(id) => pty.rerun_command_in_pane(pane_id, cmd),
    PaneId::Plugin(_) => Err(anyhow!("cannot respawn plugin panes")).with_context(err_context),
}

Prevention

When it happens

Trigger: An Action that re-runs a pane command (e.g. the 'run command again' / CommandPaneReRun flow) is dispatched with a PaneId::Plugin instead of PaneId::Terminal — usually a caller passing the wrong pane id type or a plugin pane id where a terminal id was expected.

Common situations: Plugin code capturing a pane id from an event and feeding it to a re-run/respawn action without checking whether the pane is a terminal; keybindings or sessions scripts that reference a plugin pane's id.

Related errors


AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16). Data as JSON: /api/errors/d828a15fc1341257. Report an issue: GitHub.