zellij-org/zellij · error · anyhow::Error

Invalid Direction: {}

Error message

Invalid Direction: {}

What it means

Returned by proto_i32_to_direction when the i32 does not match any of the four known Direction values (Left/Right/Up/Down). It covers both corrupted out-of-range integers and the proto3 unset value, since Unspecified = 0 falls into the wildcard arm here too.

Source

Thrown at zellij-utils/src/ipc/protobuf_conversion.rs:3502

        x if x == ProtoResize::Increase as i32 => ProtoResize::Increase,
        x if x == ProtoResize::Decrease as i32 => ProtoResize::Decrease,
        _ => return Err(anyhow!("Invalid ResizeType: {}", resize)),
    };
    match proto_resize {
        ProtoResize::Increase => Ok(crate::data::Resize::Increase),
        ProtoResize::Decrease => Ok(crate::data::Resize::Decrease),
        ProtoResize::Unspecified => Err(anyhow!("Unspecified ResizeType")),
    }
}

fn proto_i32_to_direction(direction: i32) -> Result<crate::data::Direction> {
    use crate::client_server_contract::client_server_contract::Direction as ProtoDirection;
    let proto_direction = match direction {
        x if x == ProtoDirection::Left as i32 => ProtoDirection::Left,
        x if x == ProtoDirection::Right as i32 => ProtoDirection::Right,
        x if x == ProtoDirection::Up as i32 => ProtoDirection::Up,
        x if x == ProtoDirection::Down as i32 => ProtoDirection::Down,
        _ => return Err(anyhow!("Invalid Direction: {}", direction)),
    };
    match proto_direction {
        ProtoDirection::Left => Ok(crate::data::Direction::Left),
        ProtoDirection::Right => Ok(crate::data::Direction::Right),
        ProtoDirection::Up => Ok(crate::data::Direction::Up),
        ProtoDirection::Down => Ok(crate::data::Direction::Down),
        ProtoDirection::Unspecified => Err(anyhow!("Unspecified direction")),
    }
}

fn proto_i32_to_search_direction(direction: i32) -> Result<crate::input::actions::SearchDirection> {
    use crate::client_server_contract::client_server_contract::SearchDirection as ProtoSearchDirection;
    let proto_direction = match direction {
        x if x == ProtoSearchDirection::Up as i32 => ProtoSearchDirection::Up,
        x if x == ProtoSearchDirection::Down as i32 => ProtoSearchDirection::Down,
        _ => return Err(anyhow!("Invalid SearchDirection: {}", direction)),
    };
    match proto_direction {

View on GitHub (pinned to 98a0837077)

Solutions

  1. Set the direction field explicitly on the sending side before serializing
  2. Run the same zellij version on both sides of the connection
  3. Pre-validate the integer against the known variant values before converting

Example fix

// before
let dir = proto_i32_to_direction(action.direction)?;

// after
let dir = proto_i32_to_direction(action.direction)
    .context("direction field missing or invalid in Action")?;
Defensive patterns

Strategy: validation

Validate before calling

use crate::client_server_contract::client_server_contract::Direction as ProtoDirection;
fn direction_value_is_valid(v: i32) -> bool {
    v == ProtoDirection::Left as i32 || v == ProtoDirection::Right as i32
        || v == ProtoDirection::Up as i32 || v == ProtoDirection::Down as i32
}

Type guard

fn is_valid_direction(v: i32) -> bool {
    direction_value_is_valid(v)
}

Try / catch

let dir = proto_i32_to_direction(action.direction)
    .map_err(|e| e.context(format!("invalid direction field {}", action.direction)))?;

Prevention

When it happens

Trigger: Decoding an Action carrying a direction field that was never set (0) or holds an unknown integer — e.g. Move/Resize actions from a mismatched client version or a malformed IPC message.

Common situations: Client/server version skew; external tooling or plugins constructing protobuf actions without setting direction; partially initialized messages in tests.

Related errors


AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16). Data as JSON: /api/errors/2de2190ce267d9c1. Report an issue: GitHub.