fix(tauri): prevent CEF init panic on second launch via single-instance plugin (#1510)

This commit is contained in:
Steven Enamakel
2026-05-11 19:35:03 -07:00
committed by GitHub
parent 018619dc6a
commit e3749a0383
4 changed files with 48 additions and 1 deletions
+15
View File
@@ -41,6 +41,7 @@ dependencies = [
"tauri-plugin-global-shortcut",
"tauri-plugin-notification",
"tauri-plugin-opener",
"tauri-plugin-single-instance",
"tauri-plugin-updater",
"tauri-runtime-cef",
"tempfile",
@@ -7261,6 +7262,20 @@ dependencies = [
"zbus",
]
[[package]]
name = "tauri-plugin-single-instance"
version = "2.4.0"
source = "git+https://github.com/tauri-apps/plugins-workspace?rev=c6561ab6b4f9e7f650d4fc8c53fd8acc9b65b9b2#c6561ab6b4f9e7f650d4fc8c53fd8acc9b65b9b2"
dependencies = [
"serde",
"serde_json",
"tauri",
"thiserror 2.0.18",
"tracing",
"windows-sys 0.60.2",
"zbus",
]
[[package]]
name = "tauri-plugin-updater"
version = "2.10.1"
+7
View File
@@ -46,6 +46,12 @@ tauri-plugin-deep-link = "2.0.0"
tauri-plugin-global-shortcut = "2"
tauri-plugin-notification = { path = "vendor/tauri-plugin-notification" }
tauri-plugin-opener = "2"
# Prevents a second launch from racing into CEF init and hitting the
# `cef::initialize(...) != 1` cache-lock panic seen in production
# (Sentry OPENHUMAN-TAURI-A). The plugin acquires a per-identifier
# lock before any tauri::Builder work happens, so the secondary
# process exits cleanly after handing its argv to the primary.
tauri-plugin-single-instance = "2"
# Auto-update for the Tauri shell itself. The core sidecar already has its own
# updater (see `core_update.rs`); this plugin handles the .app/.exe/.AppImage
# bundle. Both are needed because shipping a new RPC method requires both
@@ -188,6 +194,7 @@ tauri-plugin = { path = "vendor/tauri-cef/crates/tauri-plugin" }
tauri-plugin-opener = { git = "https://github.com/tauri-apps/plugins-workspace", rev = "c6561ab6b4f9e7f650d4fc8c53fd8acc9b65b9b2" }
tauri-plugin-deep-link = { git = "https://github.com/tauri-apps/plugins-workspace", rev = "c6561ab6b4f9e7f650d4fc8c53fd8acc9b65b9b2" }
tauri-plugin-global-shortcut = { git = "https://github.com/tauri-apps/plugins-workspace", rev = "c6561ab6b4f9e7f650d4fc8c53fd8acc9b65b9b2" }
tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", rev = "c6561ab6b4f9e7f650d4fc8c53fd8acc9b65b9b2" }
tauri-plugin-notification = { path = "vendor/tauri-plugin-notification" }
[dev-dependencies]
+25
View File
@@ -1362,6 +1362,31 @@ pub fn run() {
};
let builder = builder
// Single-instance guard — MUST be the first plugin registered so the
// secondary-process exit path triggers before any other plugin setup
// (and before `Builder::build()` reaches `CefRuntime::init`). Without
// this, launching a second instance races into CEF init while the
// primary still holds the cache lock; `cef::initialize` returns 0 and
// the vendored runtime asserts (Sentry OPENHUMAN-TAURI-A — 442 events
// across Win10/11 + Linux, all releases). The callback receives the
// secondary's argv/cwd; we forward deep-link args and focus the main
// window. Deep-link payloads stay handled by `tauri-plugin-deep-link`
// — we just need to wake the primary so it observes them.
.plugin(tauri_plugin_single_instance::init(
|app: &AppHandle<AppRuntime>, args, cwd| {
// Don't log raw argv/cwd: deep-link callbacks (OAuth codes,
// magic links) can carry auth tokens that would otherwise leak
// into desktop logs and Sentry breadcrumbs. CodeRabbit on #1510.
log::info!(
"[single-instance] secondary launch detected, focusing primary (argc={}, cwd_present={})",
args.len(),
!cwd.is_empty()
);
if let Err(err) = show_main_window(app) {
log::warn!("[single-instance] failed to focus main window: {err}");
}
},
))
// Explicitly disable `open_js_links_on_click`: tauri-plugin-opener
// defaults to injecting `init-iife.js` into *every* webview — a
// global click listener that invokes `plugin:opener|open_url` via