{"record":{"id":"fad7e5000658a015","repo":"xai-org/grok-build","slug":"git-fetch-no-tags-origin-spec-timed-out-after","errorCode":null,"errorMessage":"git fetch --no-tags origin {spec} timed out after {}s{}{}","messagePattern":"git fetch --no-tags origin (.+?) timed out after (.+?)s(.+?)(.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-workspace/src/restore_fetch.rs","lineNumber":407,"sourceCode":"        })\n    }\n\n    fn wait_success(&mut self, timeout: Duration, spec: &str) -> Result<()> {\n        let child = self.child.as_mut().context(\"fetch child already reaped\")?;\n        match child.wait_timeout(timeout) {\n            Ok(Some(status)) => {\n                self.child.take();\n                let stderr = self.take_stderr();\n                if status.success() {\n                    Ok(())\n                } else {\n                    bail!(\"git fetch --no-tags origin {spec} failed ({status}): {stderr}\");\n                }\n            }\n            Ok(None) => {\n                let shutdown = self.shutdown();\n                let stderr = self.take_stderr();\n                bail!(\n                    \"git fetch --no-tags origin {spec} timed out after {}s{}{}\",\n                    timeout.as_secs(),\n                    format_shutdown_suffix(shutdown.as_ref()),\n                    format_stderr_suffix(&stderr)\n                );\n            }\n            Err(err) => {\n                let shutdown = self.shutdown();\n                let stderr = self.take_stderr();\n                Err(err).context(format!(\n                    \"waiting for git fetch origin {spec}{}{}\",\n                    format_shutdown_suffix(shutdown.as_ref()),\n                    format_stderr_suffix(&stderr)\n                ))\n            }\n        }\n    }\n","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-workspace/src/restore_fetch.rs#L389-L425","documentation":"Same timeout bail site as the fetch timeout: message text is the timed-out `git fetch --no-tags origin <spec>` failure produced in wait_success()'s Ok(None) arm, including the timeout seconds, shutdown suffix, and stderr suffix.","triggerScenarios":"wait_success() poll deadline expires before the fetch child exits — the poll loop returns Ok(None) and shutdown() is invoked.","commonSituations":"Long initial clone-equivalent fetch in CI with tight step timeouts; remote hanging mid-transfer; hung credential helper.","solutions":["Raise the wait_success() timeout budget","Ensure credentials are non-interactive so git cannot block on a prompt","Inspect format_stderr_suffix output for transfer errors","Split the fetch into smaller refspecs to reduce transfer time"],"exampleFix":"// before\nbail-budget = Duration::from_secs(60);\n// after\nbail-budget = Duration::from_secs(300); // with GIT_TERMINAL_PROMPT=0 set in env","handlingStrategy":"retry","validationCode":"// ensure environment is non-interactive before spawning\nstd::env::set_var(\"GIT_TERMINAL_PROMPT\", \"0\");","typeGuard":"fn is_fetch_timeout(err: &anyhow::Error) -> bool { err.to_string().contains(\"timed out after\") }","tryCatchPattern":"let res = waiter.wait_success(timeout).await;\nif let Err(e) = &res {\n    if e.to_string().contains(\"timed out after\") {\n        // shutdown suffix present: child was killed; retry with larger budget and backoff\n    }\n}","preventionTips":["Set generous, configurable fetch timeouts (not hard-coded seconds)","Run with GIT_TERMINAL_PROMPT=0 and pre-provisioned credentials","Check stderr suffix after a timeout for transfer or auth stalls","Use --depth/shallow fetches where full history is unnecessary"],"tags":["git","fetch","timeout"],"backgroundTag":"git-fetch-timeout","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}