{"record":{"id":"7229bf803a2d6dee","repo":"xai-org/x-algorithm","slug":"invalidinput","errorCode":"InvalidInput","errorMessage":"copy_url must be host:port, got {}","messagePattern":"copy_url must be host:port, got (.+?)","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"phoenix/crates/serving/xai-recsys-engine/src/checkpoint_proxy.rs","lineNumber":97,"sourceCode":"            num_trainers,\n            last_prefix: tokio::sync::Mutex::new(String::new()),\n            downloading: AtomicBool::new(false),\n            max_entries,\n            verify_checksums,\n            download_concurrency,\n            request_timeout,\n        }\n    }\n\n    async fn resolve_and_connect(&self) -> Result<Vec<transport::Channel>, io::Error> {\n        let (scheme, hostport) = if let Some(rest) = self.copy_url.strip_prefix(\"https://\") {\n            (\"https\", rest)\n        } else {\n            (\"http\", self.copy_url.trim_start_matches(\"http://\"))\n        };\n        let tls = crate::tls::ClientTlsOptions::from_env()?;\n        let (name, port) = hostport.rsplit_once(':').ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::InvalidInput,\n                format!(\"copy_url must be host:port, got {}\", self.copy_url),\n            )\n        })?;\n\n        let addrs: Vec<SocketAddr> = format!(\"{}:{}\", name, port).to_socket_addrs()?.collect();\n\n        if addrs.is_empty() {\n            return Err(io::Error::new(\n                io::ErrorKind::NotFound,\n                format!(\"DNS resolution returned 0 addresses for {}\", name),\n            ));\n        }\n\n        let dns_count = addrs.len();\n\n        let connect_timeout = std::time::Duration::from_secs(\n            std::env::var(\"COPY_PORT_CONNECT_TIMEOUT_SECS\")","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/phoenix/crates/serving/xai-recsys-engine/src/checkpoint_proxy.rs#L79-L115","documentation":"resolve_and_connect splits copy_url on the LAST colon via rsplit_once(':'); if there is no colon at all (no host:port), it returns InvalidInput. The URL scheme prefix is stripped beforehand, so the remainder must literally contain host:port.","triggerScenarios":"Setting copy_url to a bare hostname like 'trainer1' with no port, or a malformed value like 'host:' / trailing garbage where rsplit_once fails, when poll_and_download runs.","commonSituations":"Env var or CLI flag for the checkpoint copy URL misconfigured; passing an https:// URL with no explicit port; whitespace or empty string in copy_url.","solutions":["Set copy_url to explicit host:port, e.g. 'trainer-0:50051'","Include the port even when using https (the code only auto-handles the scheme)","Check for empty/mispasted env values (COPY_URL) before launch"],"exampleFix":"# before\n--copy-url trainer-0\n\n# after\n--copy-url trainer-0:50051","handlingStrategy":"validation","validationCode":"fn valid_copy_url(u: &str) -> bool {\n    let s = u.trim().trim_start_matches(\"http://\").trim_start_matches(\"https://\");\n    match s.rsplit_once(':') { Some((h, p)) => !h.is_empty() && p.parse::<u16>().is_ok(), _ => false }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always configure copy_url as host:port with an explicit port","Fail fast at startup on invalid config instead of during download"],"tags":["configuration","url-parsing","invalid-input"],"backgroundTag":"invalid-hostport-config","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}