libnyanpasu/clash-nyanpasu · error

URL not provided

Error message

URL not provided

What it means

When the process connects to an existing primary instance's local socket, it becomes the secondary instance and must forward the deep-link URL. The library assumes the URL was passed as the first CLI argument (`std::env::args().nth(1)`) and panics with 'URL not provided' if it is absent. This is an environment/launch-contract violation: the second launch of the app did not carry the deep-link URL as argv[1].

Source

Thrown at backend/tauri-plugin-deep-link/src/windows.rs:166

                match LocalSocketStream::connect(name.clone()).await {
                    Ok(conn) => {
                        // We are the secondary instance.
                        // Prep to activate primary instance by allowing another process to take focus.

                        // A workaround to allow AllowSetForegroundWindow to succeed - press a key.
                        // This was originally used by Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=837796
                        // dummy_keypress();

                        // let primary_instance_pid = conn.peer_pid().unwrap_or(ASFW_ANY);
                        // unsafe {
                        //     let success = AllowSetForegroundWindow(primary_instance_pid) != 0;
                        //     if !success {
                        //         log::warn!("AllowSetForegroundWindow failed.");
                        //     }
                        // }
                        let (socket_rx, mut socket_tx) = conn.split();
                        let mut socket_rx = socket_rx.as_tokio_async_read();
                        let url = std::env::args().nth(1).expect("URL not provided");
                        socket_tx
                            .write_all(url.as_bytes())
                            .await
                            .expect("Failed to write to socket");
                        socket_tx
                            .write_all(b"\n")
                            .await
                            .expect("Failed to write to socket");
                        socket_tx.flush().await.expect("Failed to flush socket");

                        let mut reader = BufReader::new(&mut socket_rx);
                        let mut buf = String::new();
                        if let Err(e) = reader.read_line(&mut buf).await {
                            eprintln!("Error reading from connection: {e}");
                        }
                        buf.pop();
                        dummy_keypress();
                        let pid = buf.parse::<u32>().unwrap_or(ASFW_ANY);

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Fix the deep-link/protocol registration so the URL is appended as the first argument, e.g. `"C:\path\app.exe" "%1"` in the Windows registry command for the URL scheme.
  2. If launching programmatically, pass the deep-link URL as the first argument: `Command::new(exe).arg(url)`.
  3. When testing manually with a primary instance already running, invoke `app.exe myapp://some/path` instead of `app.exe` with no arguments.

Example fix

// before (registry command)
"C:\\apps\\myapp.exe"
// after
"C:\\apps\\myapp.exe" "%1"
Defensive patterns

Strategy: validation

Validate before calling

// Check before assuming secondary-instance handoff; guard on argv length
fn first_cli_arg() -> Option<String> {
    std::env::args().nth(1)
}

Try / catch

// The plugin panics; prevent by ensuring launcher contract, or patch prepare call site
match std::env::args().nth(1) {
    Some(url) if url.contains("://") => deep_link::prepare(APP_IDENTIFIER),
    _ => eprintln!("no deep-link URL argument; skipping single-instance handoff"),
}

Prevention

When it happens

Trigger: A second instance launched via the deep-link scheme handler without the URL as the first command-line argument — e.g. the OS/browser launched `app.exe` with no extra argument, the protocol registration template is wrong, or the process was started manually or by a test harness with no args.

Common situations: Incorrect Windows registry protocol command template (missing `"%1"`); launching the exe manually from a terminal while another instance is running; a custom launcher/updater restarting the binary without forwarding arguments; IDE run configurations that don't pass arguments.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/47647b4efede918b. Report an issue: GitHub.