{"record":{"id":"de917d0a014efcb4","repo":"cube-js/cube","slug":"wait-timeout-is-too-large","errorCode":null,"errorMessage":"wait timeout is too large","messagePattern":"wait timeout is too large","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust/cube-cli/src/wait.rs","lineNumber":131,"sourceCode":"                match last_label {\n                    Some(label) => format!(\" (last seen: {label})\"),\n                    None => String::new(),\n                },\n                if on_timeout.is_empty() {\n                    String::new()\n                } else {\n                    format!(\". {on_timeout}\")\n                },\n                match streak {\n                    Some((_, err)) => format!(\". Last error: {err}\"),\n                    None => String::new(),\n                }\n            )\n        };\n\n    let deadline = tokio::time::Instant::now()\n        .checked_add(timeout)\n        .ok_or_else(|| anyhow::anyhow!(\"wait timeout is too large\"))?;\n\n    loop {\n        let failures = streak.as_ref().map_or(0, |(count, _)| *count);\n\n        let outcome = match tokio::time::timeout_at(deadline, attempt()).await {\n            Ok(outcome) => outcome,\n            // The request itself outlived the budget. Nothing arriving later can be\n            // trusted as \"within --timeout\", so this ends the wait rather than\n            // looping back to check the clock.\n            Err(_) => return Err(timed_out(started.elapsed(), &last_label, &streak)),\n        };\n\n        match outcome {\n            Ok(Progress::Done(value)) => return Ok(value),\n            Ok(Progress::Waiting(label)) => {\n                streak = None;\n                if last_label.as_deref() != Some(label.as_str()) {\n                    eprintln!(\"{what}: {label}\");","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/rust/cube-cli/src/wait.rs#L113-L149","documentation":"`poll` computes its deadline with `Instant::checked_add(timeout)`; if the supplied timeout is so large that adding it to the current instant overflows `tokio::time::Instant`, it returns `wait timeout is too large` instead of silently wrapping. This guards against pathological timeout values (e.g. `Duration::MAX`).","triggerScenarios":"Calling `poll` with a timeout whose sum with the current monotonic clock reading exceeds the platform instant range — typically `Duration::MAX` or an absurdly large user-supplied value (test `rejects_a_timeout_that_cannot_fit_in_an_instant`).","commonSituations":"Using `Duration::MAX` as 'wait forever', multiplying a config value by the wrong unit (ms vs s), or forwarding an unset/zero-default numeric config into a Duration.","solutions":["Pass a finite, realistic timeout (e.g. `Duration::from_secs(300)`).","If you want effectively-never-timeout, cap at a large but safe value like `Duration::from_secs(86400 * 365)`.","Audit unit conversions when building the Duration from config.","Handle this error variant explicitly at the call site if timeouts are user-configurable."],"exampleFix":"// before\npoll(what, attempt(), Duration::MAX).await?\n// after\npoll(what, attempt(), Duration::from_secs(3600)).await?","handlingStrategy":"validation","validationCode":"fn timeout_ok(d: std::time::Duration) -> bool {\n    d < std::time::Duration::from_secs(86_400 * 365)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never use Duration::MAX as a timeout","Double-check ms-vs-s unit conversions","Clamp user-configured timeouts to a sane maximum"],"tags":["timeout","overflow","tokio","async"],"backgroundTag":"timeout-overflow","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}