helix-editor/helix · error · anyhow::Error
Invalid function key '{}'
Error message
Invalid function key '{}' What it means
In KeyEvent::from_str, a token longer than one char starting with 'F' is treated as a function key: the digits after F are parsed as u8 and must satisfy 1..=24 (function > 0 && function < 25). Non-numeric digits surface the u8 parse error; out-of-range numbers (0 or >= 25) fail with "Invalid function key '{n}'", where the message shows the parsed number, not the original string.
Source
Thrown at helix-view/src/input.rs:397
keys::LEFT_ALT => KeyCode::Modifier(ModifierKeyCode::LeftAlt),
keys::LEFT_SUPER => KeyCode::Modifier(ModifierKeyCode::LeftSuper),
keys::LEFT_HYPER => KeyCode::Modifier(ModifierKeyCode::LeftHyper),
keys::LEFT_META => KeyCode::Modifier(ModifierKeyCode::LeftMeta),
keys::RIGHT_SHIFT => KeyCode::Modifier(ModifierKeyCode::RightShift),
keys::RIGHT_CONTROL => KeyCode::Modifier(ModifierKeyCode::RightControl),
keys::RIGHT_ALT => KeyCode::Modifier(ModifierKeyCode::RightAlt),
keys::RIGHT_SUPER => KeyCode::Modifier(ModifierKeyCode::RightSuper),
keys::RIGHT_HYPER => KeyCode::Modifier(ModifierKeyCode::RightHyper),
keys::RIGHT_META => KeyCode::Modifier(ModifierKeyCode::RightMeta),
keys::ISO_LEVEL_3_SHIFT => KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift),
keys::ISO_LEVEL_5_SHIFT => KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift),
single if single.chars().count() == 1 => KeyCode::Char(single.chars().next().unwrap()),
function if function.len() > 1 && function.starts_with('F') => {
let function: String = function.chars().skip(1).collect();
let function = str::parse::<u8>(&function)?;
(function > 0 && function < 25)
.then_some(KeyCode::F(function))
.ok_or_else(|| anyhow!("Invalid function key '{}'", function))?
}
// Checking that the last token is empty ensures that this branch is only taken if
// `-` is used as a code. For example this branch will not be taken for `S-` (which is
// missing a code).
_ if s.ends_with('-') && tokens.last().is_some_and(|t| t.is_empty()) => {
if s == "-" {
return Ok(KeyEvent {
code: KeyCode::Char('-'),
modifiers: KeyModifiers::empty(),
});
} else {
let suggestion = format!("{}-{}", s.trim_end_matches('-'), keys::MINUS);
return Err(anyhow!(
"Key '-' cannot be used with modifiers, use '{}' instead",
suggestion
));
}
}View on GitHub (pinned to 079a789e8c)
Solutions
- Use only F1 through F24.
- For keys above F12, confirm your terminal actually encodes them (crossterm must recognize the escape sequence) before binding.
- Remove stray characters after the digits; "F1" not "F1 ".
Example fix
# before (config.toml) "F25" = "workspace_command_picker" # Err: Invalid function key '25' # after "F13" = "workspace_command_picker" # F1-F24 only
Defensive patterns
Strategy: validation
Validate before calling
fn valid_function_key(spec: &str) -> bool {
if let Some(num) = spec.strip_prefix('F') {
matches!(num.parse::<u8>(), Ok(n) if (1..=24).contains(&n))
} else {
true
}
} Type guard
fn parse_function_key(spec: &str) -> Option<crossterm::event::KeyCode> {
let num = spec.strip_prefix('F')?;
let n = num.parse::<u8>().ok()?;
(1..=24).contains(&n).then(|| crossterm::event::KeyCode::F(n))
} Try / catch
let ev = match spec.parse::<KeyEvent>() {
Ok(ev) => ev,
Err(err) if err.to_string().contains("Invalid function key") => {
return Err(anyhow!("'{spec}': only F1-F24 are supported"));
}
Err(err) => return Err(err),
}; Prevention
- Clamp bindings to F1-F24; crossterm defines no higher function keys.
- Validate generated keymaps programmatically before shipping config.
- Remember the error prints the number only, not the original string.
When it happens
Trigger: Keymap entries like "F0", "F25", "F99" (beyond crossterm's F1-F24 set), or "F1x"/"Fabc" (non-numeric suffix, which instead surfaces the integer parse error).
Common situations: Migrating configs from terminals/emulators with more function keys (some support F25+); expecting media keys to be F-keys; trailing characters after the number from copy-paste.
Related errors
- Missing key code
- Key '-' cannot be used with modifiers, use '{}' instead
- Invalid key code '{}'
- Invalid key modifier '{}-'
- Repeated key modifier '{}-'
AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16).
Data as JSON: /api/errors/fa312bf8814379c8.
Report an issue: GitHub.