zellij-org/zellij · error · anyhow::Error
ChangeFloatingPaneCoordinates missing pane_id
Error message
ChangeFloatingPaneCoordinates missing pane_id
What it means
First of two required-field checks when converting the protobuf IPC action ChangeFloatingPaneCoordinates: the action moves/reshapes a specific floating pane, so it must identify the target via the `pane_id` field. proto3 optional scalars arrive as Option in prost; if pane_id is unset the conversion fails here before coordinates are even examined.
Source
Thrown at zellij-utils/src/ipc/protobuf_conversion.rs:2866
Ok(crate::input::actions::Action::CurrentTabInfo {
output_json: current_tab_info_action.output_json,
})
},
ActionType::TogglePanePinned(_) => Ok(crate::input::actions::Action::TogglePanePinned),
ActionType::StackPanes(stack_panes_action) => {
Ok(crate::input::actions::Action::StackPanes {
pane_ids: stack_panes_action
.pane_ids
.into_iter()
.map(|id| id.try_into())
.collect::<Result<Vec<_>>>()?,
})
},
ActionType::ChangeFloatingPaneCoordinates(change_coords_action) => Ok(
crate::input::actions::Action::ChangeFloatingPaneCoordinates {
pane_id: change_coords_action
.pane_id
.ok_or_else(|| anyhow!("ChangeFloatingPaneCoordinates missing pane_id"))?
.try_into()?,
coordinates: change_coords_action
.coordinates
.ok_or_else(|| {
anyhow!("ChangeFloatingPaneCoordinates missing coordinates")
})?
.try_into()?,
},
),
ActionType::TogglePaneBorderless(toggle_borderless_action) => {
Ok(crate::input::actions::Action::TogglePaneBorderless {
pane_id: toggle_borderless_action
.pane_id
.ok_or_else(|| anyhow!("TogglePaneBorderless missing pane_id"))?
.try_into()?,
})
},
ActionType::SetPaneBorderless(set_borderless_action) => {View on GitHub (pinned to 98a0837077)
Solutions
- Set pane_id to the target pane's id (obtainable e.g. via QueryTabNames/pane-info APIs) before sending
- Regenerate client stubs from the server's proto so optional-field semantics match
- Align client and server zellij versions
- Validate both pane_id and coordinates are present before dispatching the action
Example fix
// before
ChangeFloatingPaneCoordinatesAction { coordinates: Some(coords), ..Default::default() } // pane_id: None
// after
ChangeFloatingPaneCoordinatesAction { pane_id: Some(pane_id as u64), coordinates: Some(coords) } Defensive patterns
Strategy: validation
Validate before calling
if let ActionType::ChangeFloatingPaneCoordinates(a) = action.action_type.as_ref().unwrap() {
if a.pane_id.is_none() {
anyhow::bail!("ChangeFloatingPaneCoordinates requires pane_id");
}
} Type guard
fn change_coords_action_has_pane_id(a: &ChangeFloatingPaneCoordinatesAction) -> bool {
a.pane_id.is_some()
} Try / catch
match protobuf_action.try_into() {
Ok(action) => dispatch(action),
Err(e) if e.to_string().contains("missing pane_id") => {
log::warn!("dropping pane-targeting action without pane_id");
},
Err(e) => return Err(e.context("action conversion failed")),
} Prevention
- Always resolve a concrete pane id before composing pane-targeting actions
- Re-fetch pane ids after layout changes; stale ids and missing ids both fail
- Centralize the 'which pane?' decision in one helper that returns Option<PaneId> and bails early
- Validate pane_id and coordinates together since both are required for this action
When it happens
Trigger: An IPC sender emits ChangeFloatingPaneCoordinates with only coordinates set (or fully default), omitting pane_id — the classic half-populated payload from custom clients or version-skewed stubs.
Common situations: Scripts programmatically repositioning floating panes; client generated from an older .proto where the field was not optional; debugging tools replaying captured actions with fields stripped.
Related errors
- NewFloatingPluginPane missing plugin
- ChangeFloatingPaneCoordinates missing coordinates
- TogglePaneBorderless missing pane_id
- SetPaneBorderless missing pane_id
- SetPaneColor missing pane_id
AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16).
Data as JSON: /api/errors/e3542699f95a9b9d.
Report an issue: GitHub.