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

StartOrReloadPlugin missing plugin

Error message

StartOrReloadPlugin missing plugin

What it means

Conversion of the protobuf IPC action StartOrReloadPlugin into the internal Action: this action starts a plugin not currently running, or reloads it if it is. It carries exactly one meaningful submessage, `plugin`; an incoming action without it cannot identify what to start/reload and fails conversion here.

Source

Thrown at zellij-utils/src/ipc/protobuf_conversion.rs:2693

            },
            ActionType::NewInPlacePluginPane(new_in_place_plugin_action) => {
                Ok(crate::input::actions::Action::NewInPlacePluginPane {
                    plugin: new_in_place_plugin_action
                        .plugin
                        .ok_or_else(|| anyhow!("NewInPlacePluginPane missing plugin"))?
                        .try_into()?,
                    pane_name: new_in_place_plugin_action.pane_name,
                    skip_cache: new_in_place_plugin_action.skip_cache,
                    close_replaced_pane: new_in_place_plugin_action.close_replaced_pane,
                    no_focus: new_in_place_plugin_action.no_focus,
                    tab_id: new_in_place_plugin_action.tab_id.map(|t| t as usize),
                })
            },
            ActionType::StartOrReloadPlugin(start_plugin_action) => {
                Ok(crate::input::actions::Action::StartOrReloadPlugin {
                    plugin: start_plugin_action
                        .plugin
                        .ok_or_else(|| anyhow!("StartOrReloadPlugin missing plugin"))?
                        .try_into()?,
                })
            },
            ActionType::CloseTerminalPane(close_pane_action) => {
                Ok(crate::input::actions::Action::CloseTerminalPane {
                    pane_id: close_pane_action.pane_id,
                })
            },
            ActionType::ClosePluginPane(close_pane_action) => {
                Ok(crate::input::actions::Action::ClosePluginPane {
                    pane_id: close_pane_action.pane_id,
                })
            },
            ActionType::FocusTerminalPaneWithId(focus_pane_action) => {
                Ok(crate::input::actions::Action::FocusTerminalPaneWithId {
                    pane_id: focus_pane_action.pane_id,
                    should_float_if_hidden: focus_pane_action.should_float_if_hidden,
                    should_be_in_place_if_hidden: focus_pane_action.should_be_in_place_if_hidden,

View on GitHub (pinned to 98a0837077)

Solutions

  1. Populate the `plugin` field identifying the plugin to start or reload
  2. Regenerate the protobuf stubs used by the client against the running server's version
  3. Use matching zellij versions on both ends of the IPC connection
  4. Pre-validate the action before sending; skip and log when required submessages are absent

Example fix

// before
StartPluginAction::default() // plugin: None -> "StartOrReloadPlugin missing plugin"

// after
StartPluginAction { plugin: Some(ProtobufPlugin { _location: Some(plugin_location), ..Default::default() }) }
Defensive patterns

Strategy: validation

Validate before calling

if let ActionType::StartOrReloadPlugin(a) = action.action_type.as_ref().unwrap() {
    if a.plugin.is_none() {
        anyhow::bail!("StartOrReloadPlugin requires a plugin");
    }
}

Type guard

fn start_plugin_action_is_valid(a: &StartPluginAction) -> bool {
    a.plugin.is_some()
}

Try / catch

match protobuf_action.try_into() {
    Ok(action) => dispatch(action),
    Err(e) if e.to_string().contains("StartOrReloadPlugin missing plugin") => {
        log::warn!("dropping malformed StartOrReloadPlugin action");
    },
    Err(e) => return Err(e.context("action conversion failed")),
}

Prevention

When it happens

Trigger: Sending StartOrReloadPlugin with plugin unset — default-constructed protobuf from custom tooling, stale stubs from before the action existed in its current shape, or hand-assembled payloads that only set optional wrapper fields.

Common situations: Plugin hot-reload scripts and CI tooling that drive zellij over IPC; client built from an older release talking to a newer server; partial refactors of shared proto code.

Related errors


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