Skip to content

[bug] Can't test an app with sidecar. Getting "No such file or directory (os error 2)" #13767

@alesanmed

Description

@alesanmed

Describe the bug

I'm trying to test that my application does have access to sidecar executables and can run them, so I implemented a test for that. But somehow, I keep getting "No such file or directory (os error 2)" whenever I run the tests. If I run the application in dev mode it can access the executable, if I build and run it in production mode, it also has access to the executable, but in the tests it fails.

Reproduction

Create a tauri app.
Add the sidecar in src-tauri/bin. In my example, donkidunk_ffmpeg.

Image

Add the required capabilities:

{
  "identifier": "shell:allow-execute",
  "allow": [
    {
      "name": "bin/donkidunk_ffmpeg",
      "sidecar": true
    }
  ]
}

Add the externalBin property to tauri.conf.json

"externalBin": [
  "./bin/donkidunk_ffmpeg"
]

Add a test getting the sidecar and spawning a command:

fn create_app<R: tauri::Runtime>(builder: tauri::Builder<R>) -> tauri::App<R> {
  let app = builder
      .build(tauri::generate_context!())
      .expect("error while building tauri application");

  return app;
}

#[cfg(test)]
mod tests {
    use std::process::Command;
    
    use super::*;
    use tauri_plugin_shell::ShellExt;

    #[tokio::test]
    async fn it_should_run_ffmpeg_command() -> Result<(), String> {
        let builder = tauri::test::mock_builder().plugin(tauri_plugin_shell::init());
        let app = create_app(builder);

        let ffmpeg = app.shell().sidecar("donkidunk_ffmpeg").unwrap();

        println!("Running ffmpeg command...");

        let status = Command::from(ffmpeg)
            .arg("-version")
            .spawn()
            .map_err(|e| e.to_string())?
            .wait_with_output();

        assert!(status.is_ok());

        Ok(())
    }
}

Run the test with cargo test -- --no-capture:

running 1 test
Running ffmpeg command...
Error: "No such file or directory (os error 2)"
test tests::it_should_run_ffmpeg_command ... FAILED

failures:

failures:
    tests::it_should_run_ffmpeg_command

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s

Expected behavior

It should get the sidecard and run the command successfully. If I change the sidecar with a common command (like echo "Hello, World!") it works as expected.

Full tauri info output

[✔] Environment
    - OS: Mac OS 13.7.5 x86_64 (X64)
    ✔ Xcode Command Line Tools: installed
    ✔ rustc: 1.88.0 (6b00bc388 2025-06-23)
    ✔ cargo: 1.88.0 (873a06493 2025-05-10)
    ✔ rustup: 1.28.2 (e4f3ad6f8 2025-04-28)
    ✔ Rust toolchain: stable-x86_64-apple-darwin (default)
    - node: 20.11.1
    - pnpm: 10.12.1
    - npm: 10.6.0

[-] Packages
    - tauri 🦀: 2.6.2
    - tauri-build 🦀: 2.3.0
    - wry 🦀: 0.52.1
    - tao 🦀: 0.34.0
    - @tauri-apps/api : 2.5.0 (outdated, latest: 2.6.0)
    - @tauri-apps/cli : 2.5.0 (outdated, latest: 2.6.2)

[-] Plugins
    - tauri-plugin-log 🦀: 2.6.0
    - @tauri-apps/plugin-log : 2.4.0 (outdated, latest: 2.6.0)
    - tauri-plugin-dialog 🦀: 2.3.0
    - @tauri-apps/plugin-dialog : 2.2.2 (outdated, latest: 2.3.0)
    - tauri-plugin-shell 🦀: 2.3.0
    - @tauri-apps/plugin-shell : not installed!
    - tauri-plugin-fs 🦀: 2.4.0
    - @tauri-apps/plugin-fs : 2.3.0 (outdated, latest: 2.4.0)
    - tauri-plugin-sql 🦀: 2.3.0
    - @tauri-apps/plugin-sql : 2.2.0 (outdated, latest: 2.3.0)
    - tauri-plugin-os 🦀: 2.3.0
    - @tauri-apps/plugin-os : 2.2.1 (outdated, latest: 2.3.0)
    - tauri-plugin-opener 🦀: 2.4.0
    - @tauri-apps/plugin-opener : 2.2.7 (outdated, latest: 2.4.0)

[-] App
    - build-type: bundle
    - CSP: media-src 'self' asset: http://asset.localhost blob: data:
    - frontendDist: ../build
    - devUrl: http://localhost:1420/
    - framework: Svelte
    - bundler: Vite

Additional context

If instead of creating a shell with the sidecar I create a standard rust Command manually pointing to the ffmpeg executable, it also works well.

Edit
Ok I did a bit more testing. I included this code in the command that gets the sidecar both in runtime and in tests:

let ffmpeg = app.shell().sidecar("donkidunk_ffmpeg").unwrap();

let mut command = Command::from(ffmpeg);

println!("Running command: {:?}", command.get_program());
println!("Command dir: {:?}", command.get_current_dir());
println!("Command args: {:?}", command.get_args());
println!("Command envs: {:?}", command.get_envs());

When I run the test this is the executable path: project\\path\\src-tauri\\target\\debug\\deps\\donkidunk_ffmpeg.exe, while in runtime this is the path: project\\path\\src-tauri\\target\\debug\\donkidunk_ffmpeg.exe

The first file doesn't exists, the second one does. Is there a bug with tauri copying files for tests? or guessing the sidecar path?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions