{"record":{"id":"4d475f284b9c2032","repo":"zellij-org/zellij","slug":"pagescrolldownbypaneid-missing-pane-id","errorCode":null,"errorMessage":"PageScrollDownByPaneId missing pane_id","messagePattern":"PageScrollDownByPaneId missing pane_id","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"zellij-utils/src/ipc/protobuf_conversion.rs","lineNumber":2954,"sourceCode":"                    pane_id: a\n                        .pane_id\n                        .ok_or_else(|| anyhow!(\"ScrollToBottomByPaneId missing pane_id\"))?\n                        .try_into()?,\n                })\n            },\n            ActionType::PageScrollUpByPaneId(a) => {\n                Ok(crate::input::actions::Action::PageScrollUpByPaneId {\n                    pane_id: a\n                        .pane_id\n                        .ok_or_else(|| anyhow!(\"PageScrollUpByPaneId missing pane_id\"))?\n                        .try_into()?,\n                })\n            },\n            ActionType::PageScrollDownByPaneId(a) => {\n                Ok(crate::input::actions::Action::PageScrollDownByPaneId {\n                    pane_id: a\n                        .pane_id\n                        .ok_or_else(|| anyhow!(\"PageScrollDownByPaneId missing pane_id\"))?\n                        .try_into()?,\n                })\n            },\n            ActionType::HalfPageScrollUpByPaneId(a) => {\n                Ok(crate::input::actions::Action::HalfPageScrollUpByPaneId {\n                    pane_id: a\n                        .pane_id\n                        .ok_or_else(|| anyhow!(\"HalfPageScrollUpByPaneId missing pane_id\"))?\n                        .try_into()?,\n                })\n            },\n            ActionType::HalfPageScrollDownByPaneId(a) => {\n                Ok(crate::input::actions::Action::HalfPageScrollDownByPaneId {\n                    pane_id: a\n                        .pane_id\n                        .ok_or_else(|| anyhow!(\"HalfPageScrollDownByPaneId missing pane_id\"))?\n                        .try_into()?,\n                })","sourceCodeStart":2936,"sourceCodeEnd":2972,"githubUrl":"https://github.com/zellij-org/zellij/blob/98a0837077492d53dd252ab30bc3e43e41e504f4/zellij-utils/src/ipc/protobuf_conversion.rs#L2936-L2972","documentation":"Zellij converts incoming protobuf IPC actions into its internal Action enum via TryFrom. The PageScrollDownByPaneId variant pages down the scrollback of one specific pane, so the protobuf message PageScrollDownByPaneIdAction 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, conversion fails with 'PageScrollDownByPaneId missing pane_id' and the action never executes.","triggerScenarios":"Sending an action message whose action_type is PageScrollDownByPaneId while PageScrollDownByPaneIdAction.pane_id is None - typically a prost struct built with default() or a client that only fills the oneof discriminator and not the payload.","commonSituations":"Custom clients or plugins assembling Action messages by hand; zellij client/server version mismatch where the sender's schema lacks the pane_id field; confusion with the focused-pane variant PageScrollDown which needs no pane_id.","solutions":["Populate pane_id with Some(PaneId { pane_type: Some(PaneType::Terminal(id)) }) before sending.","Use the plain PageScrollDown variant when targeting the focused pane.","Align client, server, and plugin builds on the same zellij version.","Add an Action -> proto -> Action round-trip test for every variant you send."],"exampleFix":"// before\nlet action = ActionType::PageScrollDownByPaneId(PageScrollDownByPaneIdAction {\n    pane_id: None, // -> \"PageScrollDownByPaneId missing pane_id\"\n});\n\n// after\nlet action = ActionType::PageScrollDownByPaneId(PageScrollDownByPaneIdAction {\n    pane_id: Some(PaneId {\n        pane_type: Some(PaneType::Terminal(1)),\n    }),\n});","handlingStrategy":"validation","validationCode":"fn is_sendable(a: &PageScrollDownByPaneIdAction) -> bool {\n    a.pane_id\n        .as_ref()\n        .and_then(|p| p.pane_type.as_ref())\n        .is_some()\n}","typeGuard":"fn has_valid_pane_id(a: &PageScrollDownByPaneIdAction) -> bool {\n    matches!(\n        a.pane_id.as_ref().and_then(|p| p.pane_type.as_ref()),\n        Some(pane_id::PaneType::Terminal(_)) | Some(pane_id::PaneType::Plugin(_))\n    )\n}","tryCatchPattern":"match Action::try_from(proto_action) {\n    Ok(action) => dispatch(action),\n    Err(e) if e.to_string().contains(\"PageScrollDownByPaneId missing pane_id\") => {\n        log::warn!(\"incomplete scroll action from client: {e}\");\n    },\n    Err(e) => return Err(e),\n}","preventionTips":["Prefer the focused-pane variant (PageScrollDown) when you hold no concrete pane id.","Validate pane ids resolve to live panes before constructing ByPaneId actions.","Keep client and server protobuf contracts version-locked."],"tags":["zellij","ipc","protobuf","rust","pane-id","scroll"],"backgroundTag":null,"analyzedSha":"98a0837077492d53dd252ab30bc3e43e41e504f4","analyzedAt":"2026-08-16T13:02:01.396Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}