zellij-org/zellij · error

Invalid BareKey value: {}

Error message

Invalid BareKey value: {}

What it means

Thrown by bare_key_from_proto_i32 (zellij-utils/src/ipc/enum_conversions.rs) when ProtoBareKey::from_i32 returns None, i.e. the raw i32 in the message is not a valid BareKey discriminant. This is strictly an out-of-range value, distinct from the in-range Unspecified case [74].

Source

Thrown at zellij-utils/src/ipc/enum_conversions.rs:127

    fn try_from(modifier: ProtoKeyModifier) -> Result<Self> {
        match modifier {
            ProtoKeyModifier::Ctrl => Ok(KeyModifier::Ctrl),
            ProtoKeyModifier::Alt => Ok(KeyModifier::Alt),
            ProtoKeyModifier::Shift => Ok(KeyModifier::Shift),
            ProtoKeyModifier::Super => Ok(KeyModifier::Super),
            ProtoKeyModifier::Unspecified => Err(anyhow!("Unspecified key modifier")),
        }
    }
}

// Helper functions for converting between protobuf i32 and enum types
pub fn bare_key_to_proto_i32(key: BareKey) -> i32 {
    ProtoBareKey::from(key) as i32
}

pub fn bare_key_from_proto_i32(value: i32) -> Result<BareKey> {
    let proto_key =
        ProtoBareKey::from_i32(value).ok_or_else(|| anyhow!("Invalid BareKey value: {}", value))?;
    proto_key.try_into()
}

pub fn key_modifier_to_proto_i32(modifier: KeyModifier) -> i32 {
    ProtoKeyModifier::from(modifier) as i32
}

pub fn key_modifier_from_proto_i32(value: i32) -> Result<KeyModifier> {
    let proto_modifier = ProtoKeyModifier::from_i32(value)
        .ok_or_else(|| anyhow!("Invalid KeyModifier value: {}", value))?;
    proto_modifier.try_into()
}

View on GitHub (pinned to 5cb5df5cce)

Solutions

  1. Match zellij versions on both sides of the IPC boundary (same release for client, server, and plugins).
  2. Always derive discriminants with `BareKey::X as i32` / bare_key_to_proto_i32, never magic numbers.
  3. Validate inbound i32 values with ProtoBareKey::from_i32(...).is_some() before converting, and drop/log invalid frames.

Example fix

// before
let key = bare_key_from_proto_i32(999)?; // Err("Invalid BareKey value: 999")

// after: validate, then convert
if ProtoBareKey::from_i32(raw).is_some() {
    let key = bare_key_from_proto_i32(raw)?;
}
Defensive patterns

Strategy: validation

Validate before calling

// validate the raw discriminant before converting
if ProtoBareKey::from_i32(raw).is_none() {
    log::warn!("dropping frame with unknown BareKey {raw} (version skew?)");
    return Ok(None);
}
let key = bare_key_from_proto_i32(raw)?;

Type guard

fn is_known_bare_key(v: i32) -> bool {
    ProtoBareKey::from_i32(v).is_some()
}

Try / catch

match bare_key_from_proto_i32(value) {
    Ok(key) => Some(key),
    Err(e) if e.to_string().starts_with("Invalid BareKey value") => {
        log::warn!("unknown BareKey discriminant {value}; frame dropped");
        None
    },
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: key.bare_key contains an integer outside the enum's range: version skew where a newer zellij adds key variants an older binary does not know, handcrafted/corrupted IPC frames, or code computing the discriminant incorrectly instead of using bare_key_to_proto_i32.

Common situations: Client and server from different zellij releases sharing a session; custom web/native clients hardcoding numeric values; partially corrupted protobuf payloads.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of zellij-org/zellij@5cb5df5cce (2026-08-19). Data as JSON: /api/errors/8e57c74ecbd19bd3. Report an issue: GitHub.