{"record":{"id":"3e60a8b1899c5682","repo":"zellij-org/zellij","slug":"newfloatingpluginpane-missing-plugin","errorCode":null,"errorMessage":"NewFloatingPluginPane missing plugin","messagePattern":"NewFloatingPluginPane missing plugin","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"zellij-utils/src/ipc/protobuf_conversion.rs","lineNumber":2663,"sourceCode":"            ActionType::QueryTabNames(_) => Ok(crate::input::actions::Action::QueryTabNames),\n            ActionType::NewTiledPluginPane(new_tiled_plugin_action) => {\n                Ok(crate::input::actions::Action::NewTiledPluginPane {\n                    plugin: new_tiled_plugin_action\n                        .plugin\n                        .ok_or_else(|| anyhow!(\"NewTiledPluginPane missing plugin\"))?\n                        .try_into()?,\n                    pane_name: new_tiled_plugin_action.pane_name,\n                    skip_cache: new_tiled_plugin_action.skip_cache,\n                    cwd: new_tiled_plugin_action.cwd.map(PathBuf::from),\n                    no_focus: new_tiled_plugin_action.no_focus,\n                    tab_id: new_tiled_plugin_action.tab_id.map(|t| t as usize),\n                })\n            },\n            ActionType::NewFloatingPluginPane(new_floating_plugin_action) => {\n                Ok(crate::input::actions::Action::NewFloatingPluginPane {\n                    plugin: new_floating_plugin_action\n                        .plugin\n                        .ok_or_else(|| anyhow!(\"NewFloatingPluginPane missing plugin\"))?\n                        .try_into()?,\n                    pane_name: new_floating_plugin_action.pane_name,\n                    skip_cache: new_floating_plugin_action.skip_cache,\n                    cwd: new_floating_plugin_action.cwd.map(PathBuf::from),\n                    coordinates: new_floating_plugin_action\n                        .coordinates\n                        .map(|c| c.try_into())\n                        .transpose()?,\n                    no_focus: new_floating_plugin_action.no_focus,\n                    tab_id: new_floating_plugin_action.tab_id.map(|t| t as usize),\n                })\n            },\n            ActionType::NewInPlacePluginPane(new_in_place_plugin_action) => {\n                Ok(crate::input::actions::Action::NewInPlacePluginPane {\n                    plugin: new_in_place_plugin_action\n                        .plugin\n                        .ok_or_else(|| anyhow!(\"NewInPlacePluginPane missing plugin\"))?\n                        .try_into()?,","sourceCodeStart":2645,"sourceCodeEnd":2681,"githubUrl":"https://github.com/zellij-org/zellij/blob/98a0837077492d53dd252ab30bc3e43e41e504f4/zellij-utils/src/ipc/protobuf_conversion.rs#L2645-L2681","documentation":"Conversion of the protobuf IPC action NewFloatingPluginPane into the internal Action requires the nested `plugin` message (the wasm plugin to open as a floating pane). The field is optional proto3; if unset on the wire the .ok_or_else() here aborts conversion, so the floating plugin pane is never created and the error propagates to the IPC caller.","triggerScenarios":"An IPC sender emits NewFloatingPluginPane with all-default fields (plugin: None), or with only optional fields like pane_name/cwd set — from custom clients, old stubs, or malformed payloads.","commonSituations":"Programmatic creation of floating plugin panes from scripts/plugins that forget the plugin location; client-server version mismatch after the action gained fields; partial serialization bugs.","solutions":["Always populate the `plugin` field with a valid location when sending NewFloatingPluginPane","Regenerate the client's protobuf code against the server's proto files","Pin client and server to the same zellij release","Add a pre-send validation step rejecting actions whose required submessages are missing"],"exampleFix":"// before\nNewFloatingPluginPaneAction { pane_name: Some(\"notes\".into()), ..Default::default() } // plugin: None -> error\n\n// after\nNewFloatingPluginPaneAction {\n    plugin: Some(ProtobufPlugin { _location: Some(protobu_f_plugin_location(\"zellij:notes\")), ..Default::default() }),\n    pane_name: Some(\"notes\".into()),\n    ..Default::default()\n}","handlingStrategy":"validation","validationCode":"if let ActionType::NewFloatingPluginPane(a) = action.action_type.as_ref().unwrap() {\n    if a.plugin.is_none() {\n        anyhow::bail!(\"NewFloatingPluginPane requires a plugin location\");\n    }\n}","typeGuard":"fn new_floating_plugin_action_is_valid(a: &NewFloatingPluginPaneAction) -> bool {\n    a.plugin.is_some()\n}","tryCatchPattern":"match protobuf_action.try_into() {\n    Ok(action) => dispatch(action),\n    Err(e) if e.to_string().contains(\"NewFloatingPluginPane missing plugin\") => {\n        log::warn!(\"dropping malformed NewFloatingPluginPane action\");\n    },\n    Err(e) => return Err(e.context(\"action conversion failed\")),\n}","preventionTips":["Set plugin before optional fields (pane_name, coordinates, cwd) when composing the action","Pin client and server zellij versions in deployment scripts","Validate actions centrally in one place (single choke point) rather than per call site","Log the full action name on conversion failure for quick triage"],"tags":["protobuf","ipc","action","plugin","floating-pane","validation"],"backgroundTag":null,"analyzedSha":"98a0837077492d53dd252ab30bc3e43e41e504f4","analyzedAt":"2026-08-16T13:02:01.396Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}