I am trying to use rustic within a tauri application and I am running into some issues when trying to use an OpenDALBackend within an async function.
Please note that the code snippets below are just quick reproduction examples and do not represent any reason for why I would want to use async.
The following non-async function call works completely fine:
#[tauri::command]
pub fn check_repository() -> Result<(), String> {
let mut mapped_options = BTreeMap::new();
mapped_options.insert("root".to_string(), "C:\\restic_backup".to_string());
let backend_opts = BackendOptions::default()
.options(mapped_options)
.repository("opendal:fs")
.to_backends()
.unwrap();
let repo = rustic_core::Repository::new(&RepositoryOptions::default(), &backend_opts)
.unwrap()
.open(&Credentials::password("123"))
.unwrap()
.to_indexed()
.unwrap();
let opts = CheckOptions::default().trust_cache(true);
repo.check(opts).unwrap();
Ok(())
}
As soon as I make it an async function, it will no longer work:
#[tauri::command]
pub async fn check_repository() -> Result<(), String> {
let mut mapped_options = BTreeMap::new();
mapped_options.insert("root".to_string(), "C:\\restic_backup".to_string());
let backend_opts = BackendOptions::default()
.options(mapped_options)
.repository("opendal:fs")
.to_backends()
.unwrap();
let repo = rustic_core::Repository::new(&RepositoryOptions::default(), &backend_opts)
.unwrap()
.open(&Credentials::password("123"))
.unwrap()
.to_indexed()
.unwrap();
let opts = CheckOptions::default().trust_cache(true);
repo.check(opts).unwrap();
Ok(())
}
When I change the repository to use the LocalBackend it will work with async as well:
#[tauri::command]
pub async fn check_repository() -> Result<(), String> {
let mut mapped_options = BTreeMap::new();
mapped_options.insert("root".to_string(), "C:\\restic_backup".to_string());
let backend_opts = BackendOptions::default()
.options(mapped_options)
.repository("C:\\restic_backup")
.to_backends()
.unwrap();
let repo = rustic_core::Repository::new(&RepositoryOptions::default(), &backend_opts)
.unwrap()
.open(&Credentials::password("123"))
.unwrap()
.to_indexed()
.unwrap();
let opts = CheckOptions::default().trust_cache(true);
repo.check(opts).unwrap();
Ok(())
}
The following is the log output I get when trying to run the second code snippet, which indicates that OpenDAL tries to start its own runtime, but is likely unable to because it is called within the context of the tauri::async_runtime:
[2026-06-15][15:59:28][DEBUG][opendal_service_fs::backend] backend build started: FsBuilder { config: FsConfig { root: Some("C:\\restic_backup"), atomic_write_dir: None } }
[2026-06-15][15:59:28][DEBUG][opendal_service_fs::backend] backend use root C:\restic_backup
[2026-06-15][15:59:28][DEBUG][opendal::services] service=fs name= path=config: stat started
thread 'tokio-rt-worker' (25260) panicked at C:\Users\USERNAME\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\opendal-core-0.57.0\src\blocking\operator.rs:156:21:
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.
stack backtrace:
[2026-06-15][15:59:28][DEBUG][opendal::services] service=fs name= path=config: stat finished
Is there any workaround for this or should I just resort to not using async when interacting with OpenDAL?
Apologies if there is something obvious I am missing regarding this interaction or if this is an issue that is not directly related to rustic.
I am trying to use rustic within a tauri application and I am running into some issues when trying to use an
OpenDALBackendwithin an async function.Please note that the code snippets below are just quick reproduction examples and do not represent any reason for why I would want to use async.
The following non-async function call works completely fine:
As soon as I make it an async function, it will no longer work:
When I change the repository to use the
LocalBackendit will work with async as well:The following is the log output I get when trying to run the second code snippet, which indicates that OpenDAL tries to start its own runtime, but is likely unable to because it is called within the context of the
tauri::async_runtime:Is there any workaround for this or should I just resort to not using async when interacting with OpenDAL?
Apologies if there is something obvious I am missing regarding this interaction or if this is an issue that is not directly related to rustic.