{"record":{"id":"c1e170224952eab1","repo":"ducaale/xh","slug":"connection-timeout-is-not-a-valid-number","errorCode":null,"errorMessage":"Connection timeout is not a valid number","messagePattern":"Connection timeout is not a valid number","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli.rs","lineNumber":1211,"sourceCode":"        Some(self.0).filter(|t| !t.is_zero())\n    }\n}\n\nimpl FromStr for Timeout {\n    type Err = anyhow::Error;\n\n    fn from_str(sec: &str) -> anyhow::Result<Timeout> {\n        match f64::from_str(sec) {\n            Ok(s) if !s.is_nan() => {\n                if s.is_sign_negative() {\n                    Err(anyhow!(\"Connection timeout is negative\"))\n                } else if s >= Duration::MAX.as_secs_f64() || s.is_infinite() {\n                    Err(anyhow!(\"Connection timeout is too big\"))\n                } else {\n                    Ok(Timeout(Duration::from_secs_f64(s)))\n                }\n            }\n            _ => Err(anyhow!(\"Connection timeout is not a valid number\")),\n        }\n    }\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum Proxy {\n    Http(Url),\n    Https(Url),\n    All(Url),\n}\n\nimpl FromStr for Proxy {\n    type Err = anyhow::Error;\n\n    fn from_str(s: &str) -> anyhow::Result<Self> {\n        let split_arg: Vec<&str> = s.splitn(2, ':').collect();\n        match split_arg[..] {\n            [protocol, url] => {","sourceCodeStart":1193,"sourceCodeEnd":1229,"githubUrl":"https://github.com/ducaale/xh/blob/2404aceecc08b0b2d100fedc96f57745cd5904dc/src/cli.rs#L1193-L1229","documentation":"Final fallthrough guard in Timeout's FromStr impl: f64::from_str failed for the --connection-timeout argument, meaning the input is not a parseable number (e.g. 'abc' or an empty string), or it was NaN. The match on the parse result falls into the error arm and parsing of the timeout value aborts. Fires on any non-numeric or NaN timeout input.","triggerScenarios":"Passing --timeout=abc, --timeout='', --timeout=5s (suffix not allowed), or --timeout=NaN.","commonSituations":"Including time units like '30s' or '5m' (only bare numbers/seconds are accepted); locale-formatted decimals; empty values from unset env vars.","solutions":["Pass a plain numeric value in seconds (e.g. --timeout=30)","Strip unit suffixes and convert to seconds before passing","Quote/escape values in scripts to avoid empty strings","Validate the value with f64 parsing (excluding NaN) beforehand"],"exampleFix":"# before\nhttp --timeout=30s GET example.org\n# after\nhttp --timeout=30 GET example.org","handlingStrategy":"validation","validationCode":"// validate the timeout is a plain number before invoking\nlet v: f64 = timeout_str.trim().parse().map_err(|_| \"timeout must be a plain number of seconds, no unit suffix\")?;\nif v.is_nan() { return Err(\"timeout must not be NaN\"); }","typeGuard":"fn is_valid_timeout(s: &str) -> bool {\n    s.trim().parse::<f64>().map(|v| !v.is_nan()).unwrap_or(false)\n}","tryCatchPattern":"let out = Command::new(\"http\").args([\"--timeout\", &timeout_str, \"GET\", url]).output()?;\nif !out.status.success() && String::from_utf8_lossy(&out.stderr).contains(\"not a valid number\") {\n    eprintln!(\"'{timeout_str}' is not a bare number of seconds\");\n}","preventionTips":["Pass bare numbers only; convert '30s'/'5m' to seconds yourself","Trim whitespace and guard empty env vars before passing","Reject NaN values in input validation"],"tags":["cli","timeout","parsing"],"backgroundTag":"invalid-duration-format","analyzedSha":"2404aceecc08b0b2d100fedc96f57745cd5904dc","analyzedAt":"2026-09-13T19:13:33.814Z","contentChangedAt":"2026-09-13T19:13:33.814Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}