zellij-org/zellij · error · anyhow::Error
Invalid InputMode value: {}
Error message
Invalid InputMode value: {} What it means
Thrown while converting a protobuf InputMode integer back into the native InputMode enum. The match covers every known ProtoInputMode variant and falls through to this error for anything else. It signals an out-of-range or unrecognized enum value, which almost always means data corruption or a version mismatch between the two sides of the IPC contract.
Source
Thrown at zellij-utils/src/ipc/protobuf_conversion.rs:3428
}
fn proto_i32_to_input_mode(i: i32) -> Result<InputMode> {
match ProtoInputMode::from_i32(i) {
Some(ProtoInputMode::Normal) => Ok(InputMode::Normal),
Some(ProtoInputMode::Locked) => Ok(InputMode::Locked),
Some(ProtoInputMode::Resize) => Ok(InputMode::Resize),
Some(ProtoInputMode::Pane) => Ok(InputMode::Pane),
Some(ProtoInputMode::Tab) => Ok(InputMode::Tab),
Some(ProtoInputMode::Scroll) => Ok(InputMode::Scroll),
Some(ProtoInputMode::EnterSearch) => Ok(InputMode::EnterSearch),
Some(ProtoInputMode::Search) => Ok(InputMode::Search),
Some(ProtoInputMode::RenameTab) => Ok(InputMode::RenameTab),
Some(ProtoInputMode::RenamePane) => Ok(InputMode::RenamePane),
Some(ProtoInputMode::Session) => Ok(InputMode::Session),
Some(ProtoInputMode::Move) => Ok(InputMode::Move),
Some(ProtoInputMode::Prompt) => Ok(InputMode::Prompt),
Some(ProtoInputMode::Tmux) => Ok(InputMode::Tmux),
_ => Err(anyhow!("Invalid InputMode value: {}", i)),
}
}
// Additional helper functions for Action conversion
fn resize_to_proto_i32(resize: crate::data::Resize) -> i32 {
use crate::client_server_contract::client_server_contract::ResizeType;
match resize {
crate::data::Resize::Increase => ResizeType::Increase as i32,
crate::data::Resize::Decrease => ResizeType::Decrease as i32,
}
}
fn direction_to_proto_i32(direction: crate::data::Direction) -> i32 {
use crate::client_server_contract::client_server_contract::Direction as ProtoDirection;
match direction {
crate::data::Direction::Left => ProtoDirection::Left as i32,
crate::data::Direction::Right => ProtoDirection::Right as i32,
crate::data::Direction::Up => ProtoDirection::Up as i32,View on GitHub (pinned to 98a0837077)
Solutions
- Align client and server to the same zellij build so the enum sets match
- Regenerate the protobuf bindings (client_server_contract) after editing the .proto and rebuild both sides
- If accepting untrusted input, validate the i32 against the known variant set before converting
Example fix
// before
let mode = InputMode::try_from(proto_mode_i32)?; // may fail on unknown value
// after
use crate::client_server_contract::client_server_contract::InputMode as ProtoInputMode;
fn is_known_input_mode(v: i32) -> bool {
matches!(v, x if x == ProtoInputMode::Normal as i32
|| x == ProtoInputMode::Locked as i32
|| x == ProtoInputMode::Resize as i32
|| x == ProtoInputMode::Pane as i32
|| x == ProtoInputMode::Tab as i32)
}
let mode = if is_known_input_mode(proto_mode_i32) { InputMode::try_from(proto_mode_i32)? } else { InputMode::Normal }; Defensive patterns
Strategy: validation
Validate before calling
const KNOWN_INPUT_MODES: &[i32] = &[
ProtoInputMode::Normal as i32, ProtoInputMode::Locked as i32,
ProtoInputMode::Resize as i32, ProtoInputMode::Pane as i32,
ProtoInputMode::Tab as i32, ProtoInputMode::Scroll as i32,
ProtoInputMode::EnterSearch as i32, ProtoInputMode::Search as i32,
ProtoInputMode::RenameTab as i32, ProtoInputMode::RenamePane as i32,
ProtoInputMode::Session as i32, ProtoInputMode::Move as i32,
ProtoInputMode::Prompt as i32, ProtoInputMode::Tmux as i32,
];
fn is_known_input_mode(v: i32) -> bool { KNOWN_INPUT_MODES.contains(&v) } Type guard
fn is_valid_input_mode(v: i32) -> bool {
// regenerate this list from the proto enum when the contract changes
KNOWN_INPUT_MODES.contains(&v)
} Try / catch
let mode = InputMode::try_from(proto_value)
.with_context(|| format!("rejected InputMode value {} (version skew?)", proto_value))?; Prevention
- Regenerate protobuf bindings and rebuild all binaries together after .proto changes
- Reject unknown enum ints at the trust boundary with a clear version-skew message
- Fuzz the IPC decode path in CI to catch unknown-enum cases early
When it happens
Trigger: Calling the InputMode TryFrom conversion with an i32 that does not correspond to any ProtoInputMode variant: a newer enum value sent to an older binary, a corrupted message, or a manually constructed payload with an arbitrary integer.
Common situations: Mixing zellij client and server of different versions after a new InputMode variant was added; fuzzed or hand-written protobuf payloads; stale compiled contract after regenerating the .proto files.
Related errors
- Invalid ResizeType: {}
- Unspecified ResizeType
- Invalid Direction: {}
- SkipConfirm missing action
- NewTiledPluginPane missing plugin
AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16).
Data as JSON: /api/errors/06d60f48e431ac62.
Report an issue: GitHub.