libnyanpasu/clash-nyanpasu · error
invalid hotkey function: {s}
Error message
invalid hotkey function: {s} What it means
HotkeyFunc::from_str parses user-provided hotkey function name strings (from config) into the HotkeyFunc enum. Unknown strings bail with 'invalid hotkey function: {s}'. The config file contained a function name that is not one of the recognized verbs (toggle/enable/disable system proxy or tun mode, etc.).
Source
Thrown at backend/tauri/src/core/hotkey.rs:142
}
impl FromStr for HotkeyFunc {
type Err = anyhow::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s {
"open_or_close_dashboard" => Ok(HotkeyFunc::OpenOrCloseDashboard),
"clash_mode_rule" => Ok(HotkeyFunc::ClashModeRule),
"clash_mode_global" => Ok(HotkeyFunc::ClashModeGlobal),
"clash_mode_direct" => Ok(HotkeyFunc::ClashModeDirect),
"clash_mode_script" => Ok(HotkeyFunc::ClashModeScript),
"toggle_system_proxy" => Ok(HotkeyFunc::ToggleSystemProxy),
"enable_system_proxy" => Ok(HotkeyFunc::EnableSystemProxy),
"disable_system_proxy" => Ok(HotkeyFunc::DisableSystemProxy),
"toggle_tun_mode" => Ok(HotkeyFunc::ToggleTunMode),
"enable_tun_mode" => Ok(HotkeyFunc::EnableTunMode),
"disable_tun_mode" => Ok(HotkeyFunc::DisableTunMode),
_ => bail!("invalid hotkey function: {s}"),
}
}
}
pub struct Hotkey {
current: Arc<Mutex<Vec<String>>>, // 保存当前的热键设置
app_handle: Arc<Mutex<Option<AppHandle>>>,
}
// (hotkey, func)
type HotKeyOp<'a> = (&'a str, HotKeyOpType<'a>);
#[derive(Debug)]
enum HotKeyOpType<'a> {
#[allow(unused)]
Unbind(&'a str),
#[allow(unused)]
Change(&'a str, &'a str),View on GitHub (pinned to f7dbce2997)
Solutions
- Fix the config entry to use an exact supported name (e.g. toggle_system_proxy, enable_tun_mode)
- Validate hotkey config at load/patch time and reject unknown functions with a clear UI message before application
- Keep a deprecated-name alias map to migrate old function names on config load
Example fix
// config before
"hotkey": { "Ctrl+Alt+P": "toggle_sys_proxy" }
// after
"hotkey": { "Ctrl+Alt+P": "toggle_system_proxy" } Defensive patterns
Strategy: validation
Validate before calling
const VALID_FUNCS: [&str; 9] = ["open_or_close_dashboard","clash_mode_rule","clash_mode_global","clash_mode_direct","toggle_system_proxy","enable_system_proxy","disable_system_proxy","toggle_tun_mode","enable_tun_mode","disable_tun_mode"];
fn hotkey_func_valid(s: &str) -> bool { VALID_FUNCS.contains(&s) } Try / catch
match s.parse::<HotkeyFunc>() {
Ok(f) => f,
Err(e) => return Err(config_error(format!("unknown hotkey function: {e}"))),
} Prevention
- Validate hotkey function names at config load/patch time
- Use a frontend dropdown of valid verbs instead of free text
- Maintain alias mapping for renamed legacy functions
When it happens
Trigger: A verge config hotkey mapping whose value is not one of the exact known strings — typos like 'toggle_sys_proxy', older/renamed function names, or non-English entries.
Common situations: Hand-edited config files; config migrated from an older version whose function names changed; users copying hotkey configs between forks with different verbs.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid theme color: {}
- hotkey_error.invalid_hotkey
- hotkey_error.missing_super_key
- app handle is none
- cannot repair typed clash config before split_legacy_config
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/9d186134bd21f3f1.
Report an issue: GitHub.