lencx/ChatGPT · error

[view:download] Failed to open file

Error message

[view:download] Failed to open file

What it means

Panic from app_handle.shell().open(path, None) (tauri-plugin-shell opener) returning Err when the finished download's file cannot be revealed/opened with the OS default handler. The shell extension delegates to the OS: xdg-open on Linux, open on macOS, ShellExecute on Windows. It fails when the helper binary is missing, the path is invalid (empty PathBuf if Requested never stored a path), or the spawn is blocked by policy/sandbox.

Source

Thrown at src-tauri/src/core/setup.rs:85

                                        .download_dir()
                                        .expect("[view:download] Failed to get download directory");
                                    let mut locked_path = download_path
                                        .lock()
                                        .expect("[view:download] Failed to lock download path");
                                    *locked_path = download_dir.join(&destination);
                                    *destination = locked_path.clone();
                                }
                                DownloadEvent::Finished { success, .. } => {
                                    let final_path = download_path
                                        .lock()
                                        .expect("[view:download] Failed to lock download path")
                                        .clone();

                                    if success {
                                        app_handle
                                            .shell()
                                            .open(final_path.to_string_lossy(), None)
                                            .expect("[view:download] Failed to open file");
                                    }
                                }
                                _ => (),
                            }
                            true
                        }
                    })
                    .initialization_script(&AppConf::load_script(&handle, "ask.js"))
                    .initialization_script(INIT_SCRIPT);

            let titlebar_view = WebviewBuilder::new(
                "titlebar",
                WebviewUrl::App("index.html".into()),
            )
            .auto_resize();

            let ask_view =
                WebviewBuilder::new("ask", WebviewUrl::App("index.html".into()))

View on GitHub (pinned to a6de9a8b61)

Solutions

  1. Downgrade the panic to a logged error with if let Err(e) — failure to auto-open should never crash the app
  2. Guard the empty path: skip opening when final_path.as_os_str().is_empty()
  3. On Linux ensure xdg-utils is installed (xdg-open present) or declare it as a dependency
  4. Prefer showing the file in the file manager or a notification instead of auto-opening

Example fix

// before
app_handle
    .shell()
    .open(final_path.to_string_lossy(), None)
    .expect("[view:download] Failed to open file");

// after
if !final_path.as_os_str().is_empty() {
    if let Err(e) = app_handle
        .shell()
        .open(final_path.to_string_lossy(), None)
    {
        eprintln!("[view:download] Failed to open file: {e}");
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// skip opening when no path was ever recorded (Requested missed)
if final_path.as_os_str().is_empty() {
    return true;
}

Type guard

fn openable(p: &std::path::Path) -> bool {
    !p.as_os_str().is_empty() && p.exists()
}

Try / catch

if let Err(e) = app_handle
    .shell()
    .open(final_path.to_string_lossy(), None)
{
    eprintln!("[view:download] Failed to open file: {e}");
}

Prevention

When it happens

Trigger: DownloadEvent::Finished { success: true } fires and shell().open() runs with: final_path empty because a Requested event never populated download_path (e.g. download started before this handler existed or the Requested arm returned early), xdg-open absent on a minimal Linux install, the file already deleted/moved, or a sandboxed environment denying process spawn.

Common situations: Minimal Linux distros/containers without xdg-utils installed; downloads triggered programmatically or restored webview sessions that skip the Requested event leaving download_path empty; macOS quarantine/permissions blocking open; users annoyed by auto-open behavior on every download.

Related errors


AI-assisted analysis of lencx/ChatGPT@a6de9a8b61 (2026-08-16). Data as JSON: /api/errors/62b6bdc292d7b35a. Report an issue: GitHub.