From 021b069c3ee8354642f5ef8f8832530c6bfcf757 Mon Sep 17 00:00:00 2001 From: shanu Date: Mon, 18 May 2026 17:15:10 +0530 Subject: [PATCH 1/6] fix(tauri): extend CEF cache-lock preflight to Linux (OPENHUMAN-TAURI-K1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SingletonLock check that catches concurrent-launch panics on macOS (issue #864) was gated to `#[cfg(target_os = "macos")]`. The same panic fires on Linux when a second instance races `cef_initialize` and finds the SingletonLock already held. Extend `cef_preflight`: - `mod cef_preflight` now compiled on `any(macos, linux)` - `check_default_cache` gains a Linux path: honours `OPENHUMAN_CEF_CACHE_PATH` first (always set by `cef_profile::prepare_process_cache_path` before this runs), then falls back to `$XDG_CACHE_HOME//cef` or `$HOME/.cache//cef` matching the `dirs::cache_dir()` fallback used by tauri-runtime-cef New tests: - `check_default_cache_uses_configured_env_path` — env-path no-lock - `check_default_cache_env_path_held_returns_err` — env-path held - `check_default_cache_linux_xdg_fallback_no_lock` — Linux XDG fallback --- app/src-tauri/src/cef_preflight.rs | 119 +++++++++++++++++++++++++++-- 1 file changed, 113 insertions(+), 6 deletions(-) diff --git a/app/src-tauri/src/cef_preflight.rs b/app/src-tauri/src/cef_preflight.rs index b6e71d2d5f..38dd5c974c 100644 --- a/app/src-tauri/src/cef_preflight.rs +++ b/app/src-tauri/src/cef_preflight.rs @@ -1,11 +1,16 @@ -//! CEF cache-lock preflight check (macOS). +//! CEF cache-lock preflight check (macOS and Linux). //! //! When another OpenHuman instance is already running, it holds an exclusive -//! lock on the CEF user-data-dir at `~/Library/Caches/com.openhuman.app/cef`. +//! lock on the CEF user-data-dir. On macOS this is +//! `~/Library/Caches/com.openhuman.app/cef`; on Linux it is the path in +//! `OPENHUMAN_CEF_CACHE_PATH` (set by `cef_profile::prepare_process_cache_path` +//! before this module runs), falling back to `$XDG_CACHE_HOME//cef` or +//! `$HOME/.cache//cef` when the env var is absent. +//! //! The vendored `tauri-runtime-cef` crate calls `cef::initialize()` and //! asserts the result equals `1`; on lock collision it returns `0` and the //! assertion panics with a Rust backtrace and no actionable message -//! (see issue #864). +//! (Sentry OPENHUMAN-TAURI-K1 on Linux, issue #864 on macOS). //! //! This module runs *before* the Tauri builder constructs the runtime. //! It detects the lock-holder PID via Chromium's `SingletonLock` symlink and @@ -72,7 +77,12 @@ impl fmt::Display for CefLockError { impl std::error::Error for CefLockError {} -/// Resolves the macOS default CEF cache directory and runs the preflight. +/// Resolves the platform default CEF cache directory and runs the preflight. +/// +/// Checks `OPENHUMAN_CEF_CACHE_PATH` first (always set by +/// `cef_profile::prepare_process_cache_path` before this runs). Falls back +/// to the platform-specific default: `~/Library/Caches//cef` on macOS, +/// `$XDG_CACHE_HOME//cef` or `$HOME/.cache//cef` on Linux. pub fn check_default_cache() -> Result<(), CefLockError> { if let Some(configured) = std::env::var_os("OPENHUMAN_CEF_CACHE_PATH") { let configured = PathBuf::from(configured); @@ -84,10 +94,22 @@ pub fn check_default_cache() -> Result<(), CefLockError> { } let home = std::env::var_os("HOME").ok_or(CefLockError::NoHomeDir)?; - let cache_path = PathBuf::from(home) - .join("Library/Caches") + let home = PathBuf::from(home); + + #[cfg(target_os = "macos")] + let cache_path = home.join("Library/Caches").join(APP_IDENTIFIER).join("cef"); + + // On Linux: $XDG_CACHE_HOME//cef or $HOME/.cache//cef. + // This matches the fallback path in tauri-runtime-cef's CefRuntime::init + // (via `dirs::cache_dir()`). + #[cfg(target_os = "linux")] + let cache_path = std::env::var_os("XDG_CACHE_HOME") + .map(PathBuf::from) + .filter(|p| p.is_absolute()) + .unwrap_or_else(|| home.join(".cache")) .join(APP_IDENTIFIER) .join("cef"); + log::debug!("[cef-preflight] cache_path={}", cache_path.display()); check_cef_cache_lock(&cache_path) } @@ -310,4 +332,89 @@ mod tests { ); let _ = fs::remove_dir_all(&tmp); } + + /// `check_default_cache` must use `OPENHUMAN_CEF_CACHE_PATH` when set — + /// on both macOS and Linux the profile module always sets this before the + /// preflight runs, so the platform-specific fallback paths are irrelevant + /// in production, but the configured-path branch must work on all platforms. + #[test] + fn check_default_cache_uses_configured_env_path() { + static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); + let _guard = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner()); + + let prior = std::env::var_os("OPENHUMAN_CEF_CACHE_PATH"); + let tmp = fresh_tmp("default-cache-env"); + + std::env::set_var("OPENHUMAN_CEF_CACHE_PATH", &tmp); + let result = check_default_cache(); + + match prior { + Some(v) => std::env::set_var("OPENHUMAN_CEF_CACHE_PATH", v), + None => std::env::remove_var("OPENHUMAN_CEF_CACHE_PATH"), + } + + assert!(result.is_ok(), "expected Ok with no lock, got {result:?}"); + let _ = fs::remove_dir_all(&tmp); + } + + /// `check_default_cache` with env-path pointing to a dir holding a live lock + /// must return `CefLockError::Held`. + #[test] + fn check_default_cache_env_path_held_returns_err() { + static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); + let _guard = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner()); + + let prior = std::env::var_os("OPENHUMAN_CEF_CACHE_PATH"); + let tmp = fresh_tmp("default-cache-held"); + let me = std::process::id() as i32; + symlink(format!("testhost-{me}"), tmp.join("SingletonLock")).unwrap(); + + std::env::set_var("OPENHUMAN_CEF_CACHE_PATH", &tmp); + let result = check_default_cache(); + + match prior { + Some(v) => std::env::set_var("OPENHUMAN_CEF_CACHE_PATH", v), + None => std::env::remove_var("OPENHUMAN_CEF_CACHE_PATH"), + } + + match result { + Err(CefLockError::Held { pid, .. }) => assert_eq!(pid, me), + other => panic!("expected Held, got {other:?}"), + } + let _ = fs::remove_dir_all(&tmp); + } + + /// On Linux, `check_default_cache` without `OPENHUMAN_CEF_CACHE_PATH` set + /// must fall back to `$XDG_CACHE_HOME//cef` and return Ok when no lock + /// is present. + #[cfg(target_os = "linux")] + #[test] + fn check_default_cache_linux_xdg_fallback_no_lock() { + static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); + let _guard = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner()); + + let prior_cache = std::env::var_os("OPENHUMAN_CEF_CACHE_PATH"); + let prior_xdg = std::env::var_os("XDG_CACHE_HOME"); + std::env::remove_var("OPENHUMAN_CEF_CACHE_PATH"); + + // Redirect XDG_CACHE_HOME to a temp dir we control. + let tmp = fresh_tmp("linux-xdg-fallback"); + std::env::set_var("XDG_CACHE_HOME", &tmp); + + let result = check_default_cache(); + + std::env::remove_var("XDG_CACHE_HOME"); + match prior_cache { + Some(v) => std::env::set_var("OPENHUMAN_CEF_CACHE_PATH", v), + None => {} + } + match prior_xdg { + Some(v) => std::env::set_var("XDG_CACHE_HOME", v), + None => {} + } + + // No SingletonLock under tmp//cef — should be Ok. + assert!(result.is_ok(), "expected Ok with no lock, got {result:?}"); + let _ = fs::remove_dir_all(&tmp); + } } From 322b749ed0617af9288fbfb33830a6e421bf3eed Mon Sep 17 00:00:00 2001 From: shanu Date: Mon, 18 May 2026 17:15:50 +0530 Subject: [PATCH 2/6] fix(tauri): add Linux display-server pre-flight guard (OPENHUMAN-TAURI-K1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CEF requires a display server (X11 or Wayland) to initialise. On WSL2 without WSLg, and on headless Linux boxes, both DISPLAY and WAYLAND_DISPLAY are unset. In that case `cef_initialize` returns 0 and the vendored `tauri-runtime-cef` assertion fires (`left: 0, right: 1`) — a fatal, silent panic with no actionable error message. Adds `check_linux_display_server()` that runs before the Tauri builder (before `CefRuntime::init`) on Linux only: - If either DISPLAY or WAYLAND_DISPLAY is set → no-op, continue - If both are absent → log an error, print a human-readable message with WSL2 guidance, and exit(1) cleanly Also extends the preflight call site from `#[cfg(macos)]` to `#[cfg(any(macos, linux))]` so the SingletonLock check from commit 021b069c is wired in on Linux too. Mirrors the Windows pre-CEF single-instance guard pattern from #1723. --- app/src-tauri/src/lib.rs | 51 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/app/src-tauri/src/lib.rs b/app/src-tauri/src/lib.rs index 3190492759..7b1be24317 100644 --- a/app/src-tauri/src/lib.rs +++ b/app/src-tauri/src/lib.rs @@ -2,7 +2,7 @@ compile_error!("src-tauri host is desktop-only. Non-desktop targets are not supported."); mod cdp; -#[cfg(target_os = "macos")] +#[cfg(any(target_os = "macos", target_os = "linux"))] mod cef_preflight; mod cef_profile; mod core_process; @@ -1593,6 +1593,45 @@ fn warn_if_wsl_x11_desktop_launch() { #[cfg(not(target_os = "linux"))] fn warn_if_wsl_x11_desktop_launch() {} +/// Returns `true` if a display server is available on Linux. +/// Testable pure function: takes the env-presence booleans directly. +#[cfg(any(target_os = "linux", test))] +fn linux_display_server_present(display: bool, wayland_display: bool) -> bool { + display || wayland_display +} + +/// Pre-CEF display-server check for Linux (Sentry OPENHUMAN-TAURI-K1). +/// +/// CEF/Chromium requires X11 (`DISPLAY`) or Wayland (`WAYLAND_DISPLAY`) to +/// initialise. Without either, `cef_initialize` returns 0 and the vendored +/// `tauri-runtime-cef` asserts `result == 1` → panic `left: 0, right: 1`. +/// This is fatal and silent on WSL2 without WSLg and on any headless Linux box. +/// Detect it here and exit with a clear message before `CefRuntime::init` runs. +#[cfg(target_os = "linux")] +fn check_linux_display_server() { + if linux_display_server_present(has_non_empty_env("DISPLAY"), has_non_empty_env("WAYLAND_DISPLAY")) { + log::debug!( + "[cef-preflight] Linux display server present: DISPLAY={:?} WAYLAND_DISPLAY={:?}", + std::env::var("DISPLAY").ok(), + std::env::var("WAYLAND_DISPLAY").ok() + ); + return; + } + let msg = "[openhuman] no display server found (DISPLAY and WAYLAND_DISPLAY are both unset).\n\ + OpenHuman requires an X11 or Wayland display to run.\n\ + On WSL2: install WSLg or configure X11 forwarding from Windows.\n\ + Set DISPLAY (e.g. export DISPLAY=:0) or WAYLAND_DISPLAY before launching."; + log::error!( + "[cef-preflight] Linux display server missing — CEF cannot initialize \ + (OPENHUMAN-TAURI-K1): DISPLAY and WAYLAND_DISPLAY both unset" + ); + eprintln!("\n{msg}\n"); + std::process::exit(1); +} + +#[cfg(not(target_os = "linux"))] +fn check_linux_display_server() {} + type CefCommandLineArg = (&'static str, Option<&'static str>); fn append_platform_cef_gpu_workarounds(args: &mut Vec, os: &str, arch: &str) { @@ -1812,6 +1851,9 @@ pub fn run() { } warn_if_wsl_x11_desktop_launch(); + // Exit before CEF if no display server is available — prevents the + // `assert_eq!(cef_initialize(…), 1)` panic (OPENHUMAN-TAURI-K1). + check_linux_display_server(); // The vendored tauri-cef dev-server proxy builds a reqwest 0.13 client // (see vendor/tauri-cef/crates/tauri/src/protocol/tauri.rs) which calls @@ -1899,7 +1941,12 @@ pub fn run() { #[cfg(target_os = "macos")] process_recovery::reap_stale_openhuman_processes(); - #[cfg(target_os = "macos")] + // CEF cache-lock preflight: if another OpenHuman instance holds the CEF + // user-data-dir SingletonLock, `cef_initialize` returns 0 and the vendored + // runtime panics (`left: 0, right: 1`). Catch the collision here and exit + // cleanly. Stale locks (PID dead) are removed so crashed processes don't + // block subsequent launches. macOS: issue #864. Linux: OPENHUMAN-TAURI-K1. + #[cfg(any(target_os = "macos", target_os = "linux"))] if let Err(e) = cef_preflight::check_default_cache() { eprintln!("\n[openhuman] {e}\n"); std::process::exit(1); From 3608f925b639a3ddcd4f327a9ab8007bd4ad36c1 Mon Sep 17 00:00:00 2001 From: shanu Date: Mon, 18 May 2026 17:16:02 +0530 Subject: [PATCH 3/6] test(tauri): unit tests for Linux display-server and CEF preflight guards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - linux_display_present_with_{x11,wayland,both}: verify pure fn - linux_display_absent_without_either: no-display → false cef_preflight tests (check_default_cache_*): - uses_configured_env_path: OPENHUMAN_CEF_CACHE_PATH no-lock → Ok - env_path_held_returns_err: env-path with live lock → CefLockError::Held - linux_xdg_fallback_no_lock (#[cfg(linux)]): XDG_CACHE_HOME redirect, no lock → Ok --- app/src-tauri/src/lib.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/src-tauri/src/lib.rs b/app/src-tauri/src/lib.rs index 7b1be24317..6e27b7a032 100644 --- a/app/src-tauri/src/lib.rs +++ b/app/src-tauri/src/lib.rs @@ -3251,6 +3251,30 @@ mod tests { assert!(!should_warn_for_wsl_x11_desktop(true, true, false, true)); } + // ------------------------------------------------------------------------- + // Linux display-server pre-flight (Sentry OPENHUMAN-TAURI-K1) + // ------------------------------------------------------------------------- + + #[test] + fn linux_display_present_with_x11() { + assert!(linux_display_server_present(true, false)); + } + + #[test] + fn linux_display_present_with_wayland() { + assert!(linux_display_server_present(false, true)); + } + + #[test] + fn linux_display_present_with_both() { + assert!(linux_display_server_present(true, true)); + } + + #[test] + fn linux_display_absent_without_either() { + assert!(!linux_display_server_present(false, false)); + } + // ------------------------------------------------------------------------- // Platform constants (issue #1012 Sentry tagging) // ------------------------------------------------------------------------- From 26c5b41df2ca492b345f9553a705b577c7680b37 Mon Sep 17 00:00:00 2001 From: shanu Date: Mon, 18 May 2026 17:48:12 +0530 Subject: [PATCH 4/6] fix(tauri): pass --no-sandbox to CEF when running as root on Linux (OPENHUMAN-TAURI-K1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sentry trace shows the panic originates in environments running as root (uid=0) under `/root/.hermes/profiles/coder-bot/home` — CI / coder-bot / Docker containers. The display server was present (Xvfb), so the earlier display-server check does not fire. The issue is Chromium's browser-process root-user check: `cef::initialize` returns 0 unless `--no-sandbox` is passed on the command line. The `no_sandbox: 1` field in `cef::Settings` disables the sub-process sandbox but does NOT satisfy this separate root-user guard. Fix: in `append_platform_cef_gpu_workarounds`, detect `uid == 0` via `nix::unistd::getuid()` (already a dependency) and append `--no-sandbox` to the CEF command-line args. No-op on non-root users and on Windows/macOS (cfg-gated). Also adds the `user` feature to the `nix` dependency (needed for `getuid()`; previously only `signal` was enabled). Tests: - linux_root_uid_detected: uid 0 → true - linux_non_root_uid_not_detected: uid 1000/1 → false --- app/src-tauri/Cargo.toml | 2 +- app/src-tauri/src/lib.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/app/src-tauri/Cargo.toml b/app/src-tauri/Cargo.toml index 598f7422f0..0295fcb751 100644 --- a/app/src-tauri/Cargo.toml +++ b/app/src-tauri/Cargo.toml @@ -129,7 +129,7 @@ cef = { version = "=146.4.1", default-features = false } openhuman_core = { path = "../..", package = "openhuman", default-features = false } [target.'cfg(unix)'.dependencies] -nix = { version = "0.29", default-features = false, features = ["signal"] } +nix = { version = "0.29", default-features = false, features = ["signal", "user"] } [target.'cfg(target_os = "macos")'.dependencies] objc2 = "0.6" diff --git a/app/src-tauri/src/lib.rs b/app/src-tauri/src/lib.rs index 6e27b7a032..17f1507451 100644 --- a/app/src-tauri/src/lib.rs +++ b/app/src-tauri/src/lib.rs @@ -1634,6 +1634,13 @@ fn check_linux_display_server() {} type CefCommandLineArg = (&'static str, Option<&'static str>); +/// Returns `true` when the process is running as root (UID 0) on Linux. +/// Testable pure function; takes the uid directly. +#[cfg(any(target_os = "linux", test))] +fn linux_is_root_uid(uid: u32) -> bool { + uid == 0 +} + fn append_platform_cef_gpu_workarounds(args: &mut Vec, os: &str, arch: &str) { // Issue #1697: on Arch/Manjaro-family Linux systems, the AppImage can // abort during CEF GPU process startup when EGL context creation fails @@ -1659,6 +1666,28 @@ fn append_platform_cef_gpu_workarounds(args: &mut Vec, os: &s "[cef-startup] Intel macOS detected: adding --disable-gpu-compositing (issue #1012)" ); } + + // Sentry OPENHUMAN-TAURI-K1: `cef::initialize` returns 0 when running as + // root (uid 0) on Linux unless `--no-sandbox` is passed as a command-line + // argument. The `no_sandbox: 1` field in `cef::Settings` disables the + // sub-process sandbox but does NOT satisfy Chromium's separate root-user + // check in the browser process — that check requires the CLI flag. + // + // This hits CI / coder-bot / Docker environments (e.g. + // `/root/.hermes/profiles/coder-bot/home`) that run as root inside a + // container. Without the flag, `cef_initialize` returns 0 and the vendored + // runtime assertion fires (`left: 0, right: 1`). + #[cfg(target_os = "linux")] + { + let uid = nix::unistd::getuid().as_raw(); + if linux_is_root_uid(uid) { + args.push(("--no-sandbox", None)); + log::info!( + "[cef-startup] running as root (uid=0) on Linux: adding --no-sandbox \ + (OPENHUMAN-TAURI-K1)" + ); + } + } } pub fn run() { @@ -3275,6 +3304,17 @@ mod tests { assert!(!linux_display_server_present(false, false)); } + #[test] + fn linux_root_uid_detected() { + assert!(linux_is_root_uid(0)); + } + + #[test] + fn linux_non_root_uid_not_detected() { + assert!(!linux_is_root_uid(1000)); + assert!(!linux_is_root_uid(1)); + } + // ------------------------------------------------------------------------- // Platform constants (issue #1012 Sentry tagging) // ------------------------------------------------------------------------- From bb5894d74ac7db6fd1755b8de7f309fff2a7c96a Mon Sep 17 00:00:00 2001 From: shanu Date: Mon, 18 May 2026 18:05:27 +0530 Subject: [PATCH 5/6] style: rustfmt check_linux_display_server if-call line wrap --- app/src-tauri/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src-tauri/src/lib.rs b/app/src-tauri/src/lib.rs index 17f1507451..bc428d0d0e 100644 --- a/app/src-tauri/src/lib.rs +++ b/app/src-tauri/src/lib.rs @@ -1609,7 +1609,10 @@ fn linux_display_server_present(display: bool, wayland_display: bool) -> bool { /// Detect it here and exit with a clear message before `CefRuntime::init` runs. #[cfg(target_os = "linux")] fn check_linux_display_server() { - if linux_display_server_present(has_non_empty_env("DISPLAY"), has_non_empty_env("WAYLAND_DISPLAY")) { + if linux_display_server_present( + has_non_empty_env("DISPLAY"), + has_non_empty_env("WAYLAND_DISPLAY"), + ) { log::debug!( "[cef-preflight] Linux display server present: DISPLAY={:?} WAYLAND_DISPLAY={:?}", std::env::var("DISPLAY").ok(), From 6efc046abc8621fc1fc0729aa9361737b12c4a19 Mon Sep 17 00:00:00 2001 From: shanu Date: Mon, 18 May 2026 18:17:49 +0530 Subject: [PATCH 6/6] fix(test): shared ENV_LOCK in cef_preflight tests; guard --no-sandbox on os param - cef_preflight: replace per-test local static ENV_LOCK with a single module-level static so all env-mutating tests are serialised and cannot race (CodeRabbit suggestion) - lib.rs: add `os == "linux"` guard inside the #[cfg(linux)] block in append_platform_cef_gpu_workarounds so --no-sandbox is only appended when the os param matches, not just the compile-time target (CodeRabbit suggestion) --- app/src-tauri/src/cef_preflight.rs | 9 ++++++--- app/src-tauri/src/lib.rs | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/src-tauri/src/cef_preflight.rs b/app/src-tauri/src/cef_preflight.rs index 38dd5c974c..5050882c1c 100644 --- a/app/src-tauri/src/cef_preflight.rs +++ b/app/src-tauri/src/cef_preflight.rs @@ -223,6 +223,12 @@ mod tests { use super::*; use std::os::unix::fs::symlink; + // Shared lock for all tests that mutate process-global env vars. + // Each test previously had its own local `static ENV_LOCK`, allowing + // concurrent test threads to race on OPENHUMAN_CEF_CACHE_PATH / + // XDG_CACHE_HOME. A single module-level lock serialises them. + static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); + #[test] fn parse_target_simple() { assert_eq!( @@ -339,7 +345,6 @@ mod tests { /// in production, but the configured-path branch must work on all platforms. #[test] fn check_default_cache_uses_configured_env_path() { - static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); let _guard = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner()); let prior = std::env::var_os("OPENHUMAN_CEF_CACHE_PATH"); @@ -361,7 +366,6 @@ mod tests { /// must return `CefLockError::Held`. #[test] fn check_default_cache_env_path_held_returns_err() { - static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); let _guard = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner()); let prior = std::env::var_os("OPENHUMAN_CEF_CACHE_PATH"); @@ -390,7 +394,6 @@ mod tests { #[cfg(target_os = "linux")] #[test] fn check_default_cache_linux_xdg_fallback_no_lock() { - static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); let _guard = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner()); let prior_cache = std::env::var_os("OPENHUMAN_CEF_CACHE_PATH"); diff --git a/app/src-tauri/src/lib.rs b/app/src-tauri/src/lib.rs index bc428d0d0e..9d144b02cd 100644 --- a/app/src-tauri/src/lib.rs +++ b/app/src-tauri/src/lib.rs @@ -1683,7 +1683,7 @@ fn append_platform_cef_gpu_workarounds(args: &mut Vec, os: &s #[cfg(target_os = "linux")] { let uid = nix::unistd::getuid().as_raw(); - if linux_is_root_uid(uid) { + if os == "linux" && linux_is_root_uid(uid) { args.push(("--no-sandbox", None)); log::info!( "[cef-startup] running as root (uid=0) on Linux: adding --no-sandbox \