{"record":{"id":"2b78544b2b1ad7ef","repo":"zellij-org/zellij","slug":"halfpagescrollupbypaneid-missing-pane-id","errorCode":null,"errorMessage":"HalfPageScrollUpByPaneId missing pane_id","messagePattern":"HalfPageScrollUpByPaneId missing pane_id","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"zellij-utils/src/ipc/protobuf_conversion.rs","lineNumber":2962,"sourceCode":"                    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                })\n            },\n            ActionType::ResizeByPaneId(a) => {\n                let resize_action = a\n                    .resize_action\n                    .ok_or_else(|| anyhow!(\"ResizeByPaneId missing resize_action\"))?;\n                let resize = proto_i32_to_resize(resize_action.resize)?;\n                let direction = resize_action\n                    .direction","sourceCodeStart":2944,"sourceCodeEnd":2980,"githubUrl":"https://github.com/zellij-org/zellij/blob/98a0837077492d53dd252ab30bc3e43e41e504f4/zellij-utils/src/ipc/protobuf_conversion.rs#L2944-L2980","documentation":"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'.","triggerScenarios":"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.","commonSituations":"Plugins or automation tools that hand-build keybinding-equivalent actions; client/server version skew; intending HalfPageScrollUp (focused pane, no pane_id).","solutions":["Set pane_id: Some(PaneId { pane_type: Some(PaneType::Terminal(id)) }) on the message.","Prefer HalfPageScrollUp when the focused pane is the target.","Rebuild both sides of the IPC boundary from the same zellij tag.","Validate the message with a helper before conversion and reject early with a clear error."],"exampleFix":"// before\nlet action = ActionType::HalfPageScrollUpByPaneId(HalfPageScrollUpByPaneIdAction {\n    pane_id: None, // -> \"HalfPageScrollUpByPaneId missing pane_id\"\n});\n\n// after\nlet action = ActionType::HalfPageScrollUpByPaneId(HalfPageScrollUpByPaneIdAction {\n    pane_id: Some(PaneId {\n        pane_type: Some(PaneType::Plugin(3)),\n    }),\n});","handlingStrategy":"validation","validationCode":"fn is_sendable(a: &HalfPageScrollUpByPaneIdAction) -> 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: &HalfPageScrollUpByPaneIdAction) -> 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(\"missing pane_id\") => {\n        log::warn!(\"dropping malformed scroll action: {e}\");\n    },\n    Err(e) => return Err(e),\n}","preventionTips":["Check pane_id presence at the boundary where you build the message, not after the error.","Use named constructors like page_scroll_up(pane: PaneId) that make incomplete states unrepresentable.","Test scroll actions for both terminal and plugin pane targets."],"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"}