{"record":{"id":"22b3899e55f8d30c","repo":"helix-editor/helix","slug":"missing-key-code","errorCode":null,"errorMessage":"Missing key code","messagePattern":"Missing key code","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"helix-view/src/input.rs","lineNumber":337,"sourceCode":"        }\n        if self.modifiers.contains(KeyModifiers::SUPER) {\n            // \"-Meta\"\n            width += 5;\n        }\n        width\n    }\n\n    fn width_cjk(&self) -> usize {\n        self.width()\n    }\n}\n\nimpl std::str::FromStr for KeyEvent {\n    type Err = Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let mut tokens: Vec<_> = s.split('-').collect();\n        let mut code = match tokens.pop().ok_or_else(|| anyhow!(\"Missing key code\"))? {\n            keys::BACKSPACE => KeyCode::Backspace,\n            keys::ENTER => KeyCode::Enter,\n            keys::LEFT => KeyCode::Left,\n            keys::RIGHT => KeyCode::Right,\n            keys::UP => KeyCode::Up,\n            keys::DOWN => KeyCode::Down,\n            keys::HOME => KeyCode::Home,\n            keys::END => KeyCode::End,\n            keys::PAGEUP => KeyCode::PageUp,\n            keys::PAGEDOWN => KeyCode::PageDown,\n            keys::TAB => KeyCode::Tab,\n            keys::DELETE => KeyCode::Delete,\n            keys::INSERT => KeyCode::Insert,\n            keys::NULL => KeyCode::Null,\n            keys::ESC => KeyCode::Esc,\n            keys::SPACE => KeyCode::Char(' '),\n            keys::MINUS => KeyCode::Char('-'),\n            keys::LESS_THAN => KeyCode::Char('<'),","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/helix-editor/helix/blob/079a789e8cb08ead67f19e1971a1b7438b37354b/helix-view/src/input.rs#L319-L355","documentation":"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 ''\".","triggerScenarios":"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.","commonSituations":"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.","solutions":["Always include a key code after the modifiers: \"c\", \"C-c\", \"ret\", \"space\".","Reject empty strings before parsing so the user gets a clearer message.","Treat seeing this error as a signal that an empty/degenerate key string reached the parser."],"exampleFix":"// before\n let ev = \"C-\".parse::<KeyEvent>()?;\n\n// after\n let ev = \"C-c\".parse::<KeyEvent>()?;","handlingStrategy":"validation","validationCode":"fn has_key_code(spec: &str) -> bool {\n    !spec.is_empty() && spec.split('-').last().is_some_and(|t| !t.is_empty() || spec == \"-\")\n}","typeGuard":null,"tryCatchPattern":"let ev = spec.parse::<KeyEvent>().map_err(|e| anyhow!(\"bad key spec '{spec}': {e}\"))?;","preventionTips":["Reject empty or modifier-only strings before parsing.","Build key specs from (code, modifiers) pairs rather than string concatenation."],"tags":["keymap","input","helix","rust"],"backgroundTag":null,"analyzedSha":"079a789e8cb08ead67f19e1971a1b7438b37354b","analyzedAt":"2026-08-16T09:09:59.668Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}