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
- Downgrade the panic to a logged error with if let Err(e) — failure to auto-open should never crash the app
- Guard the empty path: skip opening when final_path.as_os_str().is_empty()
- On Linux ensure xdg-utils is installed (xdg-open present) or declare it as a dependency
- 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
- Ensure xdg-utils (xdg-open) is present on Linux at install time
- Treat auto-open as best-effort UX, never a hard requirement of the download flow
- Validate the recorded path exists before spawning the OS handler
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
- [view:download] Failed to get download directory
- [core:window] Failed to build window
- [core:window] Failed to get window size
- [view:download] Failed to lock download path
- [view:main] Failed to get webview window
AI-assisted analysis of lencx/ChatGPT@a6de9a8b61 (2026-08-16).
Data as JSON: /api/errors/62b6bdc292d7b35a.
Report an issue: GitHub.