libnyanpasu/clash-nyanpasu · error
app handle is none
Error message
app handle is none
What it means
Hotkey::register looks up the stored Tauri AppHandle to access global_shortcut manager; if it is None it bails with 'app handle is none'. This means hotkey registration was attempted before the Tauri app handle was stored in the Hotkey struct (or after teardown). It's a lifecycle invariant violation inside the hotkey service.
Source
Thrown at backend/tauri/src/core/hotkey.rs:254
// Validate super key requirement
if !Self::validate_super_key(hotkey) {
bail!("{}", t!("hotkey_error.missing_super_key"));
}
Ok(())
}
/// Check if the hotkey contains a super key modifier (case-insensitive)
pub fn validate_super_key(hotkey: &str) -> bool {
let hotkey_lower = hotkey.to_lowercase();
SUPER_KEYS
.iter()
.any(|key| hotkey_lower.contains(&key.to_lowercase()))
}
fn register(&self, hotkey: &str, func: &str) -> Result<()> {
let app_handle = self.app_handle.lock();
if app_handle.is_none() {
bail!("app handle is none");
}
let manager = app_handle.as_ref().unwrap().global_shortcut();
if manager.is_registered(hotkey) {
manager.unregister(hotkey)?;
}
let hotkey_func: HotkeyFunc = func.trim().parse()?;
manager.on_shortcut(hotkey, move |app_handle, hotkey, ev| {
if let ShortcutState::Pressed = ev.state {
tracing::info!("hotkey pressed: {}", hotkey);
hotkey_func.execute(app_handle);
}
})?;
log::info!(target: "app", "register hotkey {hotkey} {func}");
Ok(())View on GitHub (pinned to f7dbce2997)
Solutions
- Ensure update()/register() is only called after the app handle is injected (post-setup initialization order)
- Queue pending registrations and flush them once the handle becomes available
- Migrate per actor-migration: own registration in a HotkeyActor whose startup arguments include the shortcut adapter, removing the None case
- Improve the error message to mention hotkey registration before app initialization
Example fix
// before
let app_handle = self.app_handle.lock();
if app_handle.is_none() {
bail!("app handle is none");
}
// after
let Some(app_handle) = self.app_handle.lock().as_ref() else {
log::warn!("hotkey registration skipped: app handle not ready");
return Ok(());
}; Defensive patterns
Strategy: try-catch
Validate before calling
fn hotkeys_ready(h: &Hotkey) -> bool {
h.app_handle.lock().is_some()
} Try / catch
if let Err(e) = hotkey.update() {
log::warn!("hotkey registration deferred: {e}");
pending_registration.store(true, Ordering::Relaxed);
} Prevention
- Initialize hotkeys only after app handle injection
- Queue registrations until the handle is available
- Inject a shortcut adapter at startup (HotkeyActor) instead of an Option handle
When it happens
Trigger: update() re-registering all hotkeys before app setup completes or after the handle was cleared; enabling hotkeys in config applied during early startup before the handle exists.
Common situations: Config with enable_hotkey loaded before Tauri setup finished; tests constructing Hotkey without an app handle; restart/teardown races.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- update_systray unhandled error
- app_handle is not exist
- invalid hotkey function: {s}
- hotkey_error.invalid_hotkey
- hotkey_error.missing_super_key
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/ca938964ebbfa866.
Report an issue: GitHub.