{"record":{"id":"8014878d72aaf6d9","repo":"tauri-apps/tauri","slug":"failed-to-select-external-ip","errorCode":null,"errorMessage":"failed to select external IP","messagePattern":"failed to select external IP","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri-cli/src/mobile/mod.rs","lineNumber":205,"sourceCode":"        .map(|(_, ipaddr)| ipaddr)\n        .filter(|ipaddr| match ipaddr {\n          IpAddr::V4(i) => i != &Ipv4Addr::LOCALHOST,\n          IpAddr::V6(i) => i.to_string().ends_with(\"::2\"),\n\n        })\n        .collect();\n      match addresses.as_slice() {\n        [] => panic!(\"No external IP detected.\"),\n        [ipaddr] => *ipaddr,\n        _ => {\n          let selected = dialoguer::Select::with_theme(&dialoguer::theme::ColorfulTheme::default())\n            .with_prompt(\n              \"Failed to detect external IP, What IP should we use to access your development server?\",\n            )\n            .items(&addresses)\n            .default(0)\n            .interact()\n            .expect(\"failed to select external IP\");\n          *addresses.get(selected).unwrap()\n        }\n      }\n    };\n\n    let ip = if force {\n      prompt_for_ip()\n    } else {\n      local_ip_address::local_ip().unwrap_or_else(|_| prompt_for_ip())\n    };\n    log::info!(\"Using {ip} to access the development server.\");\n    ip\n  })\n}\n\nstruct DevUrlConfig {\n  no_dev_server_wait: bool,\n}","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/tauri-apps/tauri/blob/52e4b6e71d8632a7e648f866c442e287ecddee34/crates/tauri-cli/src/mobile/mod.rs#L187-L223","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run the command in a real interactive terminal (or use an IDE terminal pane) so the prompt can be answered.","Reduce ambiguity: disconnect the VPN or extra adapters so only one plausible IP remains.","Export CI=true so dialoguer resolves without an interactive terminal (it falls back to the default selection).","If piping, ensure stdin stays open and attached to a TTY (`script -qec 'tauri android dev' /dev/null`)."],"exampleFix":"# before: CI job with no TTY and a VPN interface -> panics\n- run: npx tauri android dev\n\n# after: non-interactive-safe\n- run: CI=true npx tauri android dev","handlingStrategy":"validation","validationCode":"# Guarantee a non-interactive-safe environment before mobile dev\nif [ ! -t 0 ]; then export CI=true; fi   # dialoguer then resolves without a TTY\n[ -t 0 ] || [ \"${CI:-}\" = \"true\" ] || { echo 'no TTY and CI unset — IP prompt would panic'; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set CI=true for tauri mobile commands in pipelines and scripts.","Run interactive dev in a real terminal; don't pipe stdin.","Reduce interface ambiguity by disconnecting VPNs so the automatic local_ip() path succeeds without a prompt."],"tags":["mobile","interactive-prompt","tty","network","ci"],"backgroundTag":"non-interactive-terminal-prompt","analyzedSha":"52e4b6e71d8632a7e648f866c442e287ecddee34","analyzedAt":"2026-08-20T13:59:20.734Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}