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

HalfPageScrollUpByPaneId missing pane_id

Error message

HalfPageScrollUpByPaneId missing pane_id

What it means

Zellij converts incoming protobuf IPC actions into its internal Action enum via TryFrom. The HalfPageScrollUpByPaneId variant scrolls a specific pane up by half a page, so HalfPageScrollUpByPaneIdAction must carry the optional pane_id field (PaneId oneof: Terminal(u32) or Plugin(u32)). If the variant is chosen but pane_id is None, conversion stops with 'HalfPageScrollUpByPaneId missing pane_id'.

Source

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

                    pane_id: a
                        .pane_id
                        .ok_or_else(|| anyhow!("PageScrollUpByPaneId missing pane_id"))?
                        .try_into()?,
                })
            },
            ActionType::PageScrollDownByPaneId(a) => {
                Ok(crate::input::actions::Action::PageScrollDownByPaneId {
                    pane_id: a
                        .pane_id
                        .ok_or_else(|| anyhow!("PageScrollDownByPaneId missing pane_id"))?
                        .try_into()?,
                })
            },
            ActionType::HalfPageScrollUpByPaneId(a) => {
                Ok(crate::input::actions::Action::HalfPageScrollUpByPaneId {
                    pane_id: a
                        .pane_id
                        .ok_or_else(|| anyhow!("HalfPageScrollUpByPaneId missing pane_id"))?
                        .try_into()?,
                })
            },
            ActionType::HalfPageScrollDownByPaneId(a) => {
                Ok(crate::input::actions::Action::HalfPageScrollDownByPaneId {
                    pane_id: a
                        .pane_id
                        .ok_or_else(|| anyhow!("HalfPageScrollDownByPaneId missing pane_id"))?
                        .try_into()?,
                })
            },
            ActionType::ResizeByPaneId(a) => {
                let resize_action = a
                    .resize_action
                    .ok_or_else(|| anyhow!("ResizeByPaneId missing resize_action"))?;
                let resize = proto_i32_to_resize(resize_action.resize)?;
                let direction = resize_action
                    .direction

View on GitHub (pinned to 98a0837077)

Solutions

  1. Set pane_id: Some(PaneId { pane_type: Some(PaneType::Terminal(id)) }) on the message.
  2. Prefer HalfPageScrollUp when the focused pane is the target.
  3. Rebuild both sides of the IPC boundary from the same zellij tag.
  4. Validate the message with a helper before conversion and reject early with a clear error.

Example fix

// before
let action = ActionType::HalfPageScrollUpByPaneId(HalfPageScrollUpByPaneIdAction {
    pane_id: None, // -> "HalfPageScrollUpByPaneId missing pane_id"
});

// after
let action = ActionType::HalfPageScrollUpByPaneId(HalfPageScrollUpByPaneIdAction {
    pane_id: Some(PaneId {
        pane_type: Some(PaneType::Plugin(3)),
    }),
});
Defensive patterns

Strategy: validation

Validate before calling

fn is_sendable(a: &HalfPageScrollUpByPaneIdAction) -> bool {
    a.pane_id
        .as_ref()
        .and_then(|p| p.pane_type.as_ref())
        .is_some()
}

Type guard

fn has_valid_pane_id(a: &HalfPageScrollUpByPaneIdAction) -> bool {
    matches!(
        a.pane_id.as_ref().and_then(|p| p.pane_type.as_ref()),
        Some(pane_id::PaneType::Terminal(_)) | Some(pane_id::PaneType::Plugin(_))
    )
}

Try / catch

match Action::try_from(proto_action) {
    Ok(action) => dispatch(action),
    Err(e) if e.to_string().contains("missing pane_id") => {
        log::warn!("dropping malformed scroll action: {e}");
    },
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: An IPC action whose action_type oneof is HalfPageScrollUpByPaneId while the inner pane_id is None - e.g. constructing the prost message with defaults, or a sender built from a stale generated contract.

Common situations: Plugins or automation tools that hand-build keybinding-equivalent actions; client/server version skew; intending HalfPageScrollUp (focused pane, no pane_id).

Related errors


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