helix-editor/helix · warning · anyhow::Error

Missing key code

Error message

Missing key code

What it means

KeyEvent::from_str splits the key spec on '-' and pops the last token as the key code; "Missing key code" fires when there is no token to pop. Since str::split always yields at least one element (possibly empty), this branch is a defensive guard that is effectively unreachable — an empty string instead reaches the fallthrough and fails as "Invalid key code ''".

Source

Thrown at helix-view/src/input.rs:337

        }
        if self.modifiers.contains(KeyModifiers::SUPER) {
            // "-Meta"
            width += 5;
        }
        width
    }

    fn width_cjk(&self) -> usize {
        self.width()
    }
}

impl std::str::FromStr for KeyEvent {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut tokens: Vec<_> = s.split('-').collect();
        let mut code = match tokens.pop().ok_or_else(|| anyhow!("Missing key code"))? {
            keys::BACKSPACE => KeyCode::Backspace,
            keys::ENTER => KeyCode::Enter,
            keys::LEFT => KeyCode::Left,
            keys::RIGHT => KeyCode::Right,
            keys::UP => KeyCode::Up,
            keys::DOWN => KeyCode::Down,
            keys::HOME => KeyCode::Home,
            keys::END => KeyCode::End,
            keys::PAGEUP => KeyCode::PageUp,
            keys::PAGEDOWN => KeyCode::PageDown,
            keys::TAB => KeyCode::Tab,
            keys::DELETE => KeyCode::Delete,
            keys::INSERT => KeyCode::Insert,
            keys::NULL => KeyCode::Null,
            keys::ESC => KeyCode::Esc,
            keys::SPACE => KeyCode::Char(' '),
            keys::MINUS => KeyCode::Char('-'),
            keys::LESS_THAN => KeyCode::Char('<'),

View on GitHub (pinned to 079a789e8c)

Solutions

  1. Always include a key code after the modifiers: "c", "C-c", "ret", "space".
  2. Reject empty strings before parsing so the user gets a clearer message.
  3. Treat seeing this error as a signal that an empty/degenerate key string reached the parser.

Example fix

// before
 let ev = "C-".parse::<KeyEvent>()?;

// after
 let ev = "C-c".parse::<KeyEvent>()?;
Defensive patterns

Strategy: validation

Validate before calling

fn has_key_code(spec: &str) -> bool {
    !spec.is_empty() && spec.split('-').last().is_some_and(|t| !t.is_empty() || spec == "-")
}

Try / catch

let ev = spec.parse::<KeyEvent>().map_err(|e| anyhow!("bad key spec '{spec}': {e}"))?;

Prevention

When it happens

Trigger: Programmatically calling "".parse::<KeyEvent>() on a string with no key-code segment; only conceivable via a hand-constructed token list, not through normal config parsing.

Common situations: Embedders building key strings by concatenation where the code part can be omitted; otherwise users never see this exact message — they see the sibling "Invalid key code ''" instead.

Related errors


AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16). Data as JSON: /api/errors/22b3899e55f8d30c. Report an issue: GitHub.