{"record":{"id":"1450472761da1874","repo":"tonhowtf/omniget","slug":"invalid-p2p-url-145047","errorCode":null,"errorMessage":"Invalid P2P URL","messagePattern":"Invalid P2P URL","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/src/platforms/p2p/mod.rs","lineNumber":117,"sourceCode":"            media_type: MediaType::Video,\n            file_size_bytes: None,\n        })\n    }\n\n    async fn download(\n        &self,\n        info: &MediaInfo,\n        opts: &DownloadOptions,\n        progress: mpsc::Sender<ProgressUpdate>,\n    ) -> anyhow::Result<DownloadResult> {\n        let url = match info.available_qualities.first() {\n            Some(q) => &q.url,\n            None => anyhow::bail!(\"No URL found in MediaInfo\"),\n        };\n\n        let code = url\n            .strip_prefix(\"p2p:\")\n            .ok_or_else(|| anyhow!(\"Invalid P2P URL\"))?;\n\n        let _ = progress.send(ProgressUpdate::percent(-2.0)).await;\n\n        tracing::info!(\"[p2p] connecting to relay for code: {}\", code);\n\n        let stream = connect_relay().await?;\n        let (read_half, mut write_half) = tokio::io::split(stream);\n        let mut reader = BufReader::new(read_half);\n\n        write_half\n            .write_all(format!(\"RECV {}\\n\", code).as_bytes())\n            .await?;\n        write_half.flush().await?;\n\n        let response = read_line(&mut reader).await?;\n        check_relay_error(&response)?;\n        if response != \"READY\" {\n            anyhow::bail!(\"Unexpected relay response: {}\", response);","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/p2p/mod.rs#L99-L135","documentation":"In download, the MediaInfo URL is expected to still carry the `p2p:` scheme so the share code can be extracted. If the stored/propagated URL lost the prefix, strip_prefix fails and this error is thrown. Unlike error 1122 this happens on the download path, after get_media_info already validated the URL.","triggerScenarios":"download() reads the MediaInfo built earlier; the `url` field no longer starts with `p2p:` (e.g. the prefix was stripped, replaced, or the MediaInfo was constructed elsewhere without the scheme).","commonSituations":"A queue entry persisted with a mutated URL; another code path builds MediaInfo with a bare code; user-edited URL; scheme lost during serialization/normalization between the fetch and download stages.","solutions":["Ensure the MediaInfo produced by get_media_info is passed to download unmodified, keeping the `p2p:` prefix intact.","Check any code that persists or transforms queue entries for accidental prefix stripping.","Log the offending URL at the error site to identify which stage corrupted it.","If constructing MediaInfo elsewhere, always format the url as format!(\"p2p:{}\", code)."],"exampleFix":"// before\nlet code = url\n    .strip_prefix(\"p2p:\")\n    .ok_or_else(|| anyhow!(\"Invalid P2P URL\"))?;\n// after\nlet code = url\n    .strip_prefix(\"p2p:\")\n    .ok_or_else(|| anyhow!(\"Invalid P2P URL: expected 'p2p:<code>', got '{}'\", url))?;","handlingStrategy":"validation","validationCode":"// Rust: check MediaInfo URL before calling download\nif !info.url.starts_with(\"p2p:\") {\n    return Err(anyhow!(\"MediaInfo url lost p2p: prefix: {:?}\", info.url));\n}","typeGuard":null,"tryCatchPattern":"match download(...).await {\n    Err(e) if e.to_string().contains(\"Invalid P2P URL\") => {\n        tracing::error!(\"MediaInfo.url was mutated between fetch and download: {e:#}\");\n    }\n    other => other?,\n}","preventionTips":["Treat MediaInfo as immutable between get_media_info and download","Never persist a stripped/parsed URL back into MediaInfo","Serialize the full p2p: URL in queue persistence","Add an integration test covering fetch -> persist -> download round-trip"],"tags":["url","validation","p2p","state"],"backgroundTag":"invalid-url-format","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}