tauri-apps / tauri-apps/plugins-workspace

[bug][opener] revealItemInDir panics on Linux: blocking zbus connection inside the async command ('Cannot start a runtime from within a runtime')

Open
#3,552 0 comments 0 reactions 0 assignees View on GitHub
plugin: opener type: bug
Dominant language
Rust
Stars
1.8k
Forks
602
Avg merge
4d 14h
Merged PRs (30d)
9

Description

### Describe the bug

On Linux, calling `revealItemInDir` from JS panics the backend with `Cannot start a runtime from within a runtime`, and the JS promise never settles (no rejection reaches the frontend).

Root cause: the plugin's Linux implementation calls `zbus::blocking::Connection::session()` synchronously inside the async `#[tauri::command]` handler, which executes on a tokio runtime worker thread ([`src/reveal_item_in_dir.rs` L206 in 2.5.3](https://github.com/tauri-apps/plugins-workspace/blob/plugins/opener-v2.5.3/plugins/opener/src/reveal_item_in_dir.rs); same code at ~L216 in 2.5.4 — both versions verified affected). When zbus is built with its `tokio` feature (common in Tauri app dep trees), `zbus::utils::block_on` drives the connection future via `tokio::runtime::Runtime::block_on`, which tokio refuses on a worker thread → panic in the command task; the invoke response is never sent.

### Reproduction

1. Tauri v2 app on Linux with `tauri-plugin-opener` 2.5.3 or 2.5.4 registered, zbus resolving with the `tokio` feature (zbus 5.14.0 here).
2. From the frontend: `import { revealItemInDir } from "@tauri-apps/plugin-opener"; await revealItemInDir("/some/existing/file");`
3. Run with `RUST_BACKTRACE=1`: the panic below is printed; no file manager opens; the JS promise stays pending forever.

Observed in a real app (repo is private, but the call site is a one-liner as above); reproduced consistently on every invocation.

### Expected behavior

The file manager opens with the item selected (the underlying D-Bus `org.freedesktop.FileManager1.ShowItems` mechanism works — calling it off-runtime succeeds), and any error rejects the JS promise instead of hanging it.

**Workaround that fixes it** (app-side): wrap the plugin's sync Rust API in a blocking task inside a custom command —

```rust
#[tauri::command]
async fn reveal_in_file_manager(path: String) -> Result<(), String> {
tauri::async_runtime::spawn_blocking(move || tauri_plugin_opener::reveal_item_in_dir(&path))
.await
.map_err(|e| e.to_string())?
.map_err(|e| e.to_string())
}
```

Verified working end-to-end. The same `spawn_blocking` treatment inside the plugin's `reveal_item_in_dir` command (or using async zbus) would fix it for everyone.

### Full `tauri info` output

```text
[⚠] Environment
- OS: Fedora 44.0.0 x86_64 (X64) (KDE on wayland)
✔ webkit2gtk-4.1: 2.52.5
✔ rsvg2: 2.62.3
✔ rustc: 1.97.1 (8bab26f4f 2026-07-14) (Fedora 1.97.1-1.fc44)
✔ cargo: 1.97.1 (c980f4866 2026-06-30) (Fedora 1.97.1-1.fc44)
⚠ rustup: not installed!
⚠ Rust toolchain: couldn't be detected! (distro rust, no rustup)
- node: 24.18.1
- pnpm: 11.1.2
- npm: 12.0.2
- bun: 1.3.14

[-] Packages
- tauri 🦀: 2.10.3, (outdated, latest: 2.11.5)
- tauri-build 🦀: 2.5.6, (outdated, latest: 2.6.3)
- wry 🦀: 0.54.4, (outdated, latest: 0.56.1)
- tao 🦀: 0.34.8, (outdated, latest: 0.37.0)
- @tauri-apps/api ⱼₛ: 2.10.1 (outdated, latest: 2.11.1)
- @tauri-apps/cli ⱼₛ: 2.10.1 (outdated, latest: 2.11.4)

[-] Plugins
- tauri-plugin-opener 🦀: 2.5.3, (outdated, latest: 2.5.4)
- @tauri-apps/plugin-opener ⱼₛ: 2.5.3 (outdated, latest: 2.5.4)
- tauri-plugin-fs 🦀: 2.5.0, (outdated, latest: 2.5.1)
- tauri-plugin-dialog 🦀: 2.7.0, (outdated, latest: 2.7.2)
- tauri-plugin-single-instance 🦀: 2.4.1, (outdated, latest: 2.4.3)

[-] App
- build-type: bundle
- CSP: unset
- frontendDist: ../dist
- devUrl: http://localhost:1420/
- framework: React
- bundler: Vite
```

(2.5.4 was also tested for the panic; the `tauri info` above is from the 2.5.3 lockfile state.)

### Stack trace

```text
thread 'tokio-rt-worker' panicked at tokio-1.52.0/src/runtime/scheduler/multi_thread/mod.rs:91:9:
Cannot start a runtime from within a runtime. This happens because a function (like `block_on`)
attempted to block the current thread while the thread is being used to drive asynchronous tasks.

16: tokio::runtime::context::runtime::enter_runtime::>
at tokio-1.52.0/src/runtime/context/runtime.rs:68:5
17: ::block_on::
at tokio-1.52.0/src/runtime/scheduler/multi_thread/mod.rs:91:9
20: zbus::utils::block_on::
at zbus-5.14.0/src/utils.rs:52:10
21: ::session
at zbus-5.14.0/src/blocking/connection/mod.rs:32:9
22: tauri_plugin_opener::reveal_item_in_dir::imp::reveal_items_in_dir
at tauri-plugin-opener-2.5.3/src/reveal_item_in_dir.rs:206:26
23: tauri_plugin_opener::reveal_item_in_dir::reveal_items_in_dir
at tauri-plugin-opener-2.5.3/src/reveal_item_in_dir.rs:64:12
24: tauri_plugin_opener::commands::reveal_item_in_dir::{closure#0}
at tauri-plugin-opener-2.5.3/src/commands.rs:75:5
```

### Additional context

- Not a duplicate of #3111 (wrong `path` key) or #3304 (Windows UNC paths) — searched open and closed issues/PRs first.
- Because the command task panics, the frontend gets no rejection: from JS this looks like the call silently doing nothing, which makes it easy to misdiagnose as a permissions problem.

-- Claude (on behalf of @superbiche)

Contributor guide

Open the contributing guide

Research direction

Start in src/commands.rs at the reveal_item_in_dir command, then inspect the Linux implementation in src/reveal_item_in_dir.rs around the blocking zbus session call. Reproduce the command on Linux with RUST_BACKTRACE=1 and verify that the file manager opens and the JS promise resolves or rejects instead of leaving the frontend pending.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
desktop-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.