tauri-apps/tauri · error

failed to read CLI options

Error message

failed to read CLI options

What it means

For mobile dev/build, the CLI reads back the CliOptions from the running app's RPC server: it reads the WebSocket address from a temp file named <identifier>-server-addr, connects, and requests "options" over JSON-RPC. This expect fires when any step inside the async block returns Err — stale/missing addr file, invalid address, WebSocket connect failure (app not running or unreachable), or a failed/malformed RPC response. Note: a missing addr file has its own panic; this one covers connect/request failures.

Source

Thrown at crates/tauri-cli/src/mobile/mod.rs:403

            "ws://{}",
            read_to_string(&addr_path).unwrap_or_else(|e| panic!(
              "failed to read missing addr file {}: {e}",
              addr_path.display()
            ))
          )
          .parse()
          .unwrap(),
        )
        .await
        .context("failed to build WebSocket client")?;
      let client: Client = ClientBuilder::default().build_with_tokio(tx, rx);
      let options: CliOptions = client
        .request("options", rpc_params![])
        .await
        .context("failed to request options")?;
      Ok::<CliOptions, Error>(options)
    })
    .expect("failed to read CLI options");

  for (k, v) in &options.vars {
    set_var(k, v);
  }
  options
}

pub fn get_app(
  target: Target,
  config: &TauriConfig,
  interface: &AppInterface,
  tauri_dir: &Path,
) -> App {
  let identifier = match target {
    Target::Android => config.identifier.replace('-', "_"),
    #[cfg(target_os = "macos")]
    Target::Ios => config.identifier.replace('_', "-"),
  };

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Confirm the app actually launches and stays alive on the device (`adb logcat` / Xcode console) before the CLI reconnects.
  2. Remove stale state: delete old <identifier>-server-addr files from TMPDIR and regenerate the mobile project if needed (tauri android/ios init).
  3. Check that your tauri.conf.json / Cargo features did not disable the mobile dev-server (tauri dev RPC) component.
  4. Verify device-to-host connectivity (adb reverse / same Wi-Fi) and retry on a clean emulator state.
  5. Update the CLI and tauri crate to matching latest versions.
Defensive patterns

Strategy: retry

Validate before calling

// Verify the app's RPC server is up before the CLI reconnects
let addr = std::fs::read_to_string(std::env::temp_dir().join(format!("{IDENTIFIER}-server-addr"))).ok();
if let Some(a) = addr {
    // probe the ws address with a short timeout before proceeding
    assert!(a.starts_with("ws://"), "stale addr file: {a}");
}

Try / catch

// Retry pattern around tauri mobile dev in scripts
for attempt in 1 2; do
  npx tauri android dev && break
  adb logcat -d --pid=$(adb shell pidof $APP_ID) | tail -50  # inspect why the app died
  [ "$attempt" -eq 2 ] && exit 1
  adb uninstall $APP_ID 2>/dev/null || true                 # clean device state

Prevention

When it happens

Trigger: Running `tauri android/ios dev` (or a follow-up build) when the on-device app's dev server is not reachable: the app crashed at startup, the tauri RPC plugin is disabled/stripped from the build, the device network blocks the reverse/forwarded connection, or the port/address changed between runs.

Common situations: Custom app configs that remove the dev-server plugin; apps that crash before starting the RPC server; firewall/USB-network issues; switching between emulator and physical device with stale state.

Related errors


AI-assisted analysis of tauri-apps/tauri@52e4b6e71d (2026-08-20). Data as JSON: /api/errors/e4bd8ae2d7a1bafc. Report an issue: GitHub.