zellij-org/zellij · error · anyhow::Error
PageScrollUpByPaneId missing pane_id
Error message
PageScrollUpByPaneId missing pane_id
What it means
Zellij converts incoming protobuf IPC actions into its internal Action enum via TryFrom. The PageScrollUpByPaneId variant targets one specific pane, so the protobuf message PageScrollUpByPaneIdAction must carry the optional field pane_id (a PaneId oneof: Terminal(u32) or Plugin(u32)). If the variant is selected but pane_id is None, the conversion aborts with 'PageScrollUpByPaneId missing pane_id' and the action is dropped before it reaches the tab/pane layer.
Source
Thrown at zellij-utils/src/ipc/protobuf_conversion.rs:2946
pane_id: a
.pane_id
.ok_or_else(|| anyhow!("ScrollToTopByPaneId missing pane_id"))?
.try_into()?,
})
},
ActionType::ScrollToBottomByPaneId(a) => {
Ok(crate::input::actions::Action::ScrollToBottomByPaneId {
pane_id: a
.pane_id
.ok_or_else(|| anyhow!("ScrollToBottomByPaneId missing pane_id"))?
.try_into()?,
})
},
ActionType::PageScrollUpByPaneId(a) => {
Ok(crate::input::actions::Action::PageScrollUpByPaneId {
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()?,
})View on GitHub (pinned to 98a0837077)
Solutions
- Set the field before sending: pane_id: Some(PaneId { pane_type: Some(PaneType::Terminal(id)) }) (or PaneType::Plugin(id) for plugin panes).
- If you meant the focused pane, send the plain PageScrollUp variant instead, which needs no pane_id.
- Make sure the client, server, and any plugins are built against the same zellij release so the protobuf contract matches.
- On the receiving side, log the serialized action and sender to identify which client omits pane_id.
Example fix
// before
let action = ActionType::PageScrollUpByPaneId(PageScrollUpByPaneIdAction {
pane_id: None, // -> "PageScrollUpByPaneId missing pane_id"
});
// after
let action = ActionType::PageScrollUpByPaneId(PageScrollUpByPaneIdAction {
pane_id: Some(PaneId {
pane_type: Some(PaneType::Terminal(1)),
}),
}); Defensive patterns
Strategy: validation
Validate before calling
fn is_sendable(a: &PageScrollUpByPaneIdAction) -> bool {
a.pane_id
.as_ref()
.and_then(|p| p.pane_type.as_ref())
.is_some()
} Type guard
fn has_valid_pane_id(a: &PageScrollUpByPaneIdAction) -> 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 zellij_utils::input::actions::Action::try_from(proto_action) {
Ok(action) => dispatch(action),
Err(e) if e.to_string().contains("missing pane_id") => {
log::warn!("dropping action with missing pane_id: {e}");
},
Err(e) => return Err(e),
} Prevention
- Never rely on prost default() for ByPaneId actions - the optional pane_id will be None.
- Centralize action construction in one builder that takes pane_id: PaneId (not Option) as a parameter.
- Round-trip test every action variant you emit: Action -> proto -> Action.
When it happens
Trigger: An IPC ClientToServerMsg whose action.action_type oneof is set to PageScrollUpByPaneId while the inner PageScrollUpByPaneIdAction.pane_id is left None - e.g. building the prost struct with ::default() and forgetting the field, or a custom client/plugin that never populates it.
Common situations: Custom tooling or plugins that hand-assemble Action messages; version skew between a zellij client and server whose generated prost contracts differ; intending the focused-pane variant PageScrollUp (no pane_id required) but sending the ByPaneId one.
Related errors
- PageScrollDownByPaneId missing pane_id
- HalfPageScrollUpByPaneId missing pane_id
- HalfPageScrollDownByPaneId missing pane_id
- ResizeByPaneId missing resize_action
- ResizeByPaneId missing pane_id
AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16).
Data as JSON: /api/errors/af63594d882fec8c.
Report an issue: GitHub.