tonhowtf/omniget · error

Unexpected relay response

Error message

Unexpected relay response: {}

What it means

download() reads a line from the relay server after connecting and expects exactly "READY"; check_relay_error already filtered explicit relay error lines. Any other line means the relay/sender protocol is out of sync (or an empty/garbage line arrived), so download aborts with this message echoing the raw response.

Solutions

  1. Verify the relay server version matches the client's relay protocol (READY handshake).
  2. Log the raw response and check for an empty line — usually means the relay socket closed; retry the connection.
  3. Check check_relay_error's recognized error lines; extend it if the relay has new error strings so they surface as real errors instead of this generic bail.
  4. Retry the download; transient relay state can produce a premature non-READY line.

Example fix

// before
let response = read_line(&mut reader).await?;
check_relay_error(&response)?;
if response != "READY" { anyhow::bail!("Unexpected relay response: {}", response); }
// after
let response = read_line(&mut reader).await?;
if response.trim().is_empty() {
    anyhow::bail!("Relay closed connection before READY; retrying");
}
check_relay_error(&response)?;
if response != "READY" { anyhow::bail!("Unexpected relay response: {:?}", response); }
Defensive patterns

Strategy: retry

Validate before calling

let md = tokio::fs::metadata(&output_path).await?; // ensure output dir writable before connecting
if !output_dir_is_writable { anyhow::bail!("Output directory not writable"); }

Try / catch

match download(opts).await {
    Err(e) if e.to_string().contains("Unexpected relay response") => {
        log::warn!("relay desync: {e}; retrying once");
        download(opts).await?; // retry with fresh connection
    }
    other => other?,
}

Prevention

When it happens

Trigger: Relay replies with a line other than "READY" after check_relay_error passes — e.g. an empty line from a closed relay connection, a protocol version mismatch, or the sender never completed handshake so the relay sent something else.

Common situations: Relay server version differs from the client (old relay sends "OK" or blank), sender dropped out between connection and READY, or a proxy/load balancer injected an HTTP error page as a line.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/837e2b729e6bb7ce. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/src/platforms/p2p/mod.rs:135

            .ok_or_else(|| anyhow!("Invalid P2P URL"))?;

        let _ = progress.send(ProgressUpdate::percent(-2.0)).await;

        tracing::info!("[p2p] connecting to relay for code: {}", code);

        let stream = connect_relay().await?;
        let (read_half, mut write_half) = tokio::io::split(stream);
        let mut reader = BufReader::new(read_half);

        write_half
            .write_all(format!("RECV {}\n", code).as_bytes())
            .await?;
        write_half.flush().await?;

        let response = read_line(&mut reader).await?;
        check_relay_error(&response)?;
        if response != "READY" {
            anyhow::bail!("Unexpected relay response: {}", response);
        }

        tracing::info!("[p2p] connected to sender via relay");

        let file_name = read_line(&mut reader).await?;
        let file_size_str = read_line(&mut reader).await?;
        let file_size: u64 = file_size_str
            .parse()
            .map_err(|_| anyhow!("Invalid file size from sender: {}", file_size_str))?;

        tracing::info!("[p2p] receiving: {} ({} bytes)", file_name, file_size);

        write_half.write_all(b"OK\n").await?;
        write_half.flush().await?;

        let _ = progress.send(ProgressUpdate::percent(0.0)).await;

        let sanitized = sanitize_filename::sanitize(&file_name);

View on GitHub (pinned to 8600b91f42)