tauri-apps/tauri · error

failed to select external IP

Error message

failed to select external IP

What it means

When multiple non-localhost IPs are found (or the simple local_ip() lookup fails and force is used), the CLI shows a dialoguer Select prompt asking which IP to use for the dev server. interact() fails when it cannot read from the terminal — no TTY, closed stdin (EOF / Ctrl-D), or a non-interactive environment — and this expect panics.

Source

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

        .map(|(_, ipaddr)| ipaddr)
        .filter(|ipaddr| match ipaddr {
          IpAddr::V4(i) => i != &Ipv4Addr::LOCALHOST,
          IpAddr::V6(i) => i.to_string().ends_with("::2"),

        })
        .collect();
      match addresses.as_slice() {
        [] => panic!("No external IP detected."),
        [ipaddr] => *ipaddr,
        _ => {
          let selected = dialoguer::Select::with_theme(&dialoguer::theme::ColorfulTheme::default())
            .with_prompt(
              "Failed to detect external IP, What IP should we use to access your development server?",
            )
            .items(&addresses)
            .default(0)
            .interact()
            .expect("failed to select external IP");
          *addresses.get(selected).unwrap()
        }
      }
    };

    let ip = if force {
      prompt_for_ip()
    } else {
      local_ip_address::local_ip().unwrap_or_else(|_| prompt_for_ip())
    };
    log::info!("Using {ip} to access the development server.");
    ip
  })
}

struct DevUrlConfig {
  no_dev_server_wait: bool,
}

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Run the command in a real interactive terminal (or use an IDE terminal pane) so the prompt can be answered.
  2. Reduce ambiguity: disconnect the VPN or extra adapters so only one plausible IP remains.
  3. Export CI=true so dialoguer resolves without an interactive terminal (it falls back to the default selection).
  4. If piping, ensure stdin stays open and attached to a TTY (`script -qec 'tauri android dev' /dev/null`).

Example fix

# before: CI job with no TTY and a VPN interface -> panics
- run: npx tauri android dev

# after: non-interactive-safe
- run: CI=true npx tauri android dev
Defensive patterns

Strategy: validation

Validate before calling

# Guarantee a non-interactive-safe environment before mobile dev
if [ ! -t 0 ]; then export CI=true; fi   # dialoguer then resolves without a TTY
[ -t 0 ] || [ "${CI:-}" = "true" ] || { echo 'no TTY and CI unset — IP prompt would panic'; exit 1; }

Prevention

When it happens

Trigger: Running `tauri android dev` / `tauri ios dev` with multiple active interfaces (VPN + ethernet + wifi) in a non-interactive context: CI without CI in the environment, piped/closed stdin, some IDE task runners that allocate no TTY.

Common situations: CI/CD pipelines or scripts invoking tauri mobile dev; running under `nohup`/cron; corporate laptops with always-on VPNs creating extra interfaces; IDE run configurations without an interactive terminal.

Related errors


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