farion1231/cc-switch · critical

error while running tauri application

Error message

error while running tauri application

What it means

This is a Rust panic from `.expect("error while running tauri application")` after `tauri::Builder::build(tauri::generate_context!())` (src-tauri/src/lib.rs:1709). `build()` returns `Result<App, tauri::Error>`, and it errs when Tauri cannot assemble the app at startup: a plugin's `initialize()` failed (this app chains single_instance, deep_link, process, dialog, opener, store, window_state, log, updater), the main window/WebView from tauri.conf.json could not be created, or the `setup` hook aborted. Tauri surfaces it this way because application assembly is treated as unrecoverable: without plugins and a webview the app cannot function. The real cause is appended to the panic message as the `Debug` of `tauri::Error` (e.g. `PluginInitialization("...")` or a WebView creation error) — always read the text after the colon.

Source

Thrown at src-tauri/src/lib.rs:1719

            // Workspace files (OpenClaw)
            commands::read_workspace_file,
            commands::write_workspace_file,
            // Daily memory files (OpenClaw workspace)
            commands::list_daily_memory_files,
            commands::read_daily_memory_file,
            commands::write_daily_memory_file,
            commands::delete_daily_memory_file,
            commands::search_daily_memory_files,
            commands::open_workspace_directory,
            // lightweight mode (for testing or low-resource environments)
            commands::enter_lightweight_mode,
            commands::exit_lightweight_mode,
            commands::is_lightweight_mode,
        ]);

    let app = builder
        .build(tauri::generate_context!())
        .expect("error while running tauri application");

    app.run(|app_handle, event| {
        // 处理退出请求(所有平台)
        if let RunEvent::ExitRequested { api, code, .. } = &event {
            match classify_exit_request(*code) {
                // code 为 None 表示运行时自动触发(如隐藏窗口的 WebView 被回收导致无存活窗口),
                // 此时应仅阻止退出、保持托盘后台运行。
                ExitRequestAction::StayInTray => {
                    log::info!("运行时触发退出请求(无存活窗口),阻止退出以保持托盘后台运行");
                    api.prevent_exit();
                    return;
                }
                // code 为 RESTART_EXIT_CODE:app.restart() / 自更新 relaunch 发起的重启。
                // 这条路径上 prevent_exit() 会被 Tauri 忽略,事件循环必定退出,随后由
                // Tauri 在 RunEvent::Exit 后用新二进制 re-exec(macOS 会按更新后的
                // Info.plist 解析可执行名)。
                //
                // 绝不能复用下面的异步清理任务:该任务在 tokio 线程调 save_window_state,

View on GitHub (pinned to 3217f72596)

Solutions

  1. Read the full panic output first: the text after 'error while running tauri application:' is the Debug of tauri::Error and names the failing subsystem (PluginInitialization("store"), webview creation, etc.) — fix that subsystem, not the expect() line.
  2. If in a headless/SSH/CI session, give the app a display: `xvfb-run -a cargo tauri dev` or set DISPLAY/WAYLAND_DISPLAY; for tests, prefer this app's lightweight mode instead of launching the full windowed build.
  3. On Linux, install the WebView runtime deps the binary links against: `sudo apt install libwebkit2gtk-4.1-0 libgtk-3-0` and verify with `ldd target/release/<binary> | grep -i webkit`; on distros with only webkit2gtk-4.0, upgrade or build against 4.0.
  4. On Windows, install the WebView2 Evergreen Runtime, or set `bundle.webviewInstallMode` to `offlineInstaller`/`embedBootstrapper` in tauri.conf.json so air-gapped machines get a runtime.
  5. If state corruption or a stale single-instance lock is the cause (app-data dir `~/.local/share/<identifier>`), delete the window-state/store files or call the existing `destroy_single_instance_lock`, then relaunch.
  6. Replace `.expect` with real Result handling that logs the error before exiting, so production failures carry a clean diagnostic instead of a bare panic (see exampleFix).

Example fix

// before (src-tauri/src/lib.rs:1707)
let app = builder
    .build(tauri::generate_context!())
    .expect("error while running tauri application");

// after
let app = match builder.build(tauri::generate_context!()) {
    Ok(app) => app,
    Err(e) => {
        eprintln!("failed to start application: {e:#}");
        log::error!("tauri build failed: {e:#}");
        std::process::exit(1);
    }
};
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight checks before builder.build() (Linux/Unix)
fn environment_ready() -> bool {
    #[cfg(target_os = "linux")]
    {
        if std::env::var_os("DISPLAY").is_none() && std::env::var_os("WAYLAND_DISPLAY").is_none() {
            eprintln!("no display server found; set DISPLAY/WAYLAND_DISPLAY or run under xvfb");
            return false;
        }
    }
    true
}

if !environment_ready() {
    std::process::exit(1);
}
let app = builder.build(tauri::generate_context!());

Type guard

// Narrow the tauri::Error variant to decide recovery vs exit
fn is_plugin_init_error(e: &tauri::Error) -> bool {
    matches!(e, tauri::Error::PluginInitialization(_))
}

Try / catch

// Rust: never .expect() on build(); match the Result and log {:#} (anyhow-style chain)
let app = match builder.build(tauri::generate_context!()) {
    Ok(app) => app,
    Err(err) if is_plugin_init_error(&err) => {
        log::error!("plugin failed to initialize: {err:#}");
        std::process::exit(1);
    }
    Err(err) => {
        log::error!("tauri app build failed: {err:#}");
        eprintln!("tauri app build failed: {err:#}");
        std::process::exit(1);
    }
};

Prevention

When it happens

Trigger: Calling `builder.build(tauri::generate_context!())` when: (1) the system cannot create a WebView — Linux without `libwebkit2gtk-4.1-0`/GTK3, Windows without the WebView2 runtime (and the default downloadBootstrapper cannot reach the network), or a headless session with no `DISPLAY`/`WAYLAND_DISPLAY` (SSH, CI, Docker); (2) a plugin fails init — tauri-plugin-store or tauri-plugin-window-state hitting an unwritable/corrupt app-data dir (`~/.local/share/<identifier>`), or an older single-instance plugin version erroring because another instance holds the lock; (3) the `setup` closure (which runs inside `build()` in Tauri v2) panics or a plugin like deep-link/updater fails its initialization with the bundled config.

Common situations: Running `cargo tauri dev` over SSH or in CI without a display server; deploying a raw binary or AppImage to a minimal Linux distro that lacks webkit2gtk 4.1 (Tauri v2 moved from 4.0 to 4.1, so images built for v1 break); Windows Server or stripped Windows without WebView2, or air-gapped machines where the bootstrapper download fails; stale single-instance socket / corrupted window-state or store JSON after a crash or force-kill; Tauri v1→v2 migrations where plugin init order or capabilities changed.

Related errors


AI-assisted analysis of farion1231/cc-switch@3217f72596 (2026-08-20). Data as JSON: /api/errors/e4d7b71ffc06481b. Report an issue: GitHub.