vercel/turborepo · critical
unhandled fkey number {n}
Error message
unhandled fkey number {n} What it means
The TUI input encoder maps crossterm F-key codes to legacy terminal escape sequences, but the match arm only covers F1 through F12 — every other F(n) hits `_ => panic!("unhandled fkey number"). Terminals using the kitty keyboard protocol can deliver F13+ (up to F35), so an extended function key reaches the panic.
Source
Thrown at crates/turborepo-ui/src/tui/input.rs:346
};
buf.push_str(s);
} else {
// Higher numbered F-keys plus modified F-keys are encoded
// using CSI instead of SS3.
let intro = match n {
1 => "\x1b[11",
2 => "\x1b[12",
3 => "\x1b[13",
4 => "\x1b[14",
5 => "\x1b[15",
6 => "\x1b[17",
7 => "\x1b[18",
8 => "\x1b[19",
9 => "\x1b[20",
10 => "\x1b[21",
11 => "\x1b[23",
12 => "\x1b[24",
_ => panic!("unhandled fkey number {n}"),
};
let encoded_mods = encode_modifiers(mods);
if encoded_mods == 0 {
// If no modifiers are held, don't send the modifier
// sequence, as the modifier encoding is a CSI-u extension.
buf.push_str(intro);
buf.push('~');
} else {
buf.push_str(intro);
buf.push(';');
buf.push_str(&(1 + encoded_mods).to_string());
buf.push('~');
}
}
}
Null => (),
CapsLock => (),View on GitHub (pinned to f9245100cf)
Solutions
- Upgrade turbo — fixed versions map or safely drop extended F-keys
- Avoid pressing/macros bound to F13+ while the TUI is focused
- Disable the kitty keyboard protocol in the terminal settings as a workaround
- Report the key and terminal if it reproduces on the latest version
Example fix
// before
let intro = match n {
1 => "\x1b[11",
// ... 2..=12 handled ...
_ => panic!("unhandled fkey number {n}"),
};
// after
if !(1..=12).contains(&n) {
return None; // or encode via CSI-u for extended keys
}
let intro = match n { /* ... */ }; Defensive patterns
Strategy: validation
Validate before calling
// Guard before encoding extended F-keys
match key.code {
crossterm::event::KeyCode::F(n) if !(1..=12).contains(&n) => {
return None; // or encode via CSI-u instead of legacy sequences
}
_ => {}
} Prevention
- In downstream TUIs, filter or clamp F-key codes above F12 before legacy encoding
- Disable the kitty keyboard protocol if your terminal emits extended F-keys turbo cannot encode
- Fuzz key-event encoders with the full KeyCode range to catch unhandled match arms
When it happens
Trigger: Encoding a KeyEvent with KeyCode::F(n) where n > 12: a keyboard/macro that emits F13–F35, a kitty-protocol terminal reporting extended keys, or a test/fuzzer synthesizing arbitrary key events.
Common situations: Power users with programmable keyboards mapping hotkeys to F13+; terminals with kitty keyboard protocol enabled; property tests generating the full KeyEvent space against the TUI.
Related errors
- failed to calculate Turbo hash: {err}
- Unable to encode '{s}'
- joined path is absolute and valid utf8: {err:?}
- collapsed path should be absolute: {err:?}
- clean should produce valid UTF-8: {err:?}
AI-assisted analysis of vercel/turborepo@f9245100cf (2026-08-17).
Data as JSON: /api/errors/a2226c3d0d14b82d.
Report an issue: GitHub.