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

SetPaneColor missing pane_id

Error message

SetPaneColor missing pane_id

What it means

Conversion of the protobuf IPC action SetPaneColor, which recolors a specific pane (fg/bg colors plus target `pane_id`). The color fields are plain values, but pane_id is an optional field checked with .ok_or_else(): an action without it identifies no pane and fails conversion here.

Source

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

                Ok(crate::input::actions::Action::SetPaneBorderless {
                    pane_id: set_borderless_action
                        .pane_id
                        .ok_or_else(|| anyhow!("SetPaneBorderless missing pane_id"))?
                        .try_into()?,
                    borderless: set_borderless_action.borderless,
                })
            },
            ActionType::TogglePaneInGroup(_) => {
                Ok(crate::input::actions::Action::TogglePaneInGroup)
            },
            ActionType::ToggleGroupMarking(_) => {
                Ok(crate::input::actions::Action::ToggleGroupMarking)
            },
            ActionType::SetPaneColor(set_pane_color_action) => {
                Ok(crate::input::actions::Action::SetPaneColor {
                    pane_id: set_pane_color_action
                        .pane_id
                        .ok_or_else(|| anyhow!("SetPaneColor missing pane_id"))?
                        .try_into()?,
                    fg: set_pane_color_action.fg,
                    bg: set_pane_color_action.bg,
                })
            },
            // Pane-targeting CLI-only variants
            ActionType::ScrollUpByPaneId(a) => {
                Ok(crate::input::actions::Action::ScrollUpByPaneId {
                    pane_id: a
                        .pane_id
                        .ok_or_else(|| anyhow!("ScrollUpByPaneId missing pane_id"))?
                        .try_into()?,
                })
            },
            ActionType::ScrollDownByPaneId(a) => {
                Ok(crate::input::actions::Action::ScrollDownByPaneId {
                    pane_id: a
                        .pane_id

View on GitHub (pinned to 98a0837077)

Solutions

  1. Populate pane_id with the target pane before sending SetPaneColor
  2. Regenerate protobuf stubs for the client from the server's zellij version
  3. Use the same zellij release on both IPC ends
  4. Validate the action's required fields before dispatch

Example fix

// before
SetPaneColorAction { fg: Some(color), bg: Some(bg), ..Default::default() } // pane_id: None

// after
SetPaneColorAction { pane_id: Some(target_pane_id as u64), fg: Some(color), bg: Some(bg) }
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

fn set_pane_color_action_is_valid(a: &SetPaneColorAction) -> bool {
    a.pane_id.is_some()
}

Try / catch

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

Prevention

When it happens

Trigger: IPC senders emitting SetPaneColor with fg/bg set but pane_id unset; default-constructed actions from custom clients; stale generated stubs that predate the pane-targeted shape of this action.

Common situations: Theme automation recoloring panes programmatically; version skew between emitter and server; scripts assuming the active pane is targeted implicitly.

Related errors


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