{"record":{"id":"d17a5d9d3423ee1a","repo":"xai-org/grok-build","slug":"http","errorCode":null,"errorMessage":"HTTP {}","messagePattern":"HTTP \\{\\}","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell-base/src/util/changelog.rs","lineNumber":216,"sourceCode":"/// Strips `**bold**` and backtick formatting from each description and returns at most `max` entries.\n/// Entries with an empty description (from tolerant deserialization) are skipped.\npub fn bullets_from_entries(entries: &[ChangelogEntry], max: usize) -> Vec<String> {\n    entries\n        .iter()\n        .filter(|e| !e.description.is_empty())\n        .take(max)\n        .map(|e| strip_markdown_inline(&e.description))\n        .collect()\n}\n\n/// Blocking HTTP fetch.\n/// Callers (`std::thread::scope` threads) are already off the tokio runtime, so no extra thread spawn is needed.\nfn fetch_blocking(url: &str) -> anyhow::Result<String> {\n    let client =\n        xai_grok_extra_ca::build_blocking_reqwest_client(|builder| builder.timeout(FETCH_TIMEOUT))?;\n    let resp = client.get(url).send()?;\n    if !resp.status().is_success() {\n        anyhow::bail!(\"HTTP {}\", resp.status());\n    }\n    Ok(resp.text()?)\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    /// Build a manager pointing at `home` directly, bypassing the global `$GROK_HOME` env so tests never race the parallel harness.\n    fn manager_for(home: &std::path::Path) -> ChangelogManager {\n        ChangelogManager {\n            md_cache: home.join(\"CHANGELOG.md\"),\n            json_cache: home.join(\"CHANGELOG.json\"),\n        }\n    }\n\n    #[test]\n    fn offline_mode_reads_seeded_disk_cache_only() {","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell-base/src/util/changelog.rs#L198-L234","documentation":"fetch_blocking performs a synchronous HTTP GET (used by fetch_json / fetch_and_cache for changelog retrieval) and bails with \"HTTP {status}\" whenever the response status is not a success (2xx). It surfaces the raw status code, e.g. \"HTTP 404 Not Found\" or \"HTTP 503 Service Unavailable\".","triggerScenarios":"Any changelog URL request returning a non-2xx status: 404 (URL moved/renamed), 403 (blocked/geo/rate-limited), 5xx (server outage); raised inside fetch_blocking, propagating to fetch_json and fetch_and_cache.","commonSituations":"The changelog hosting URL changed or the release asset was deleted; corporate proxies/CDNs returning 403; GitHub raw content rate-limiting (403/429); the server being temporarily down (5xx).","solutions":["Check the exact status in the message and open the URL in a browser/curl to confirm it is still valid.","Fix or update the changelog URL configuration if it 404s.","Retry later for 5xx/429 statuses; add backoff/retry around fetch_and_cache.","Verify no corporate proxy or firewall is rewriting/blocking the request (403)."],"exampleFix":"// before\nlet body = fetch_json(url)?;\n// after\nmatch fetch_json(url) {\n    Ok(body) => body,\n    Err(e) if e.to_string().contains(\"HTTP 4\") || e.to_string().contains(\"HTTP 5\") => {\n        eprintln!(\"changelog unavailable ({e}); using cached copy\");\n        read_cached_changelog()\n    }\n    Err(e) => return Err(e),\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match fetch_json(url) {\n    Ok(v) => v,\n    Err(e) => {\n        let msg = e.to_string();\n        if msg.starts_with(\"HTTP 5\") || msg == \"HTTP 429\" {\n            // transient: retry with backoff, then fall back to cache\n            retry_with_backoff(3, || fetch_json(url)).unwrap_or_else(|_| cached_changelog())\n        } else if msg.starts_with(\"HTTP 4\") {\n            cached_changelog() // permanent: skip fetch\n        } else {\n            Default::default()\n        }\n    }\n}","preventionTips":["Pin/verify changelog URLs and monitor them for 404s after releases","Cache the last successful fetch so failures degrade gracefully","Retry 5xx/429 with exponential backoff; don't retry 4xx client errors","Check proxy/CDN behavior if 403s appear from CI networks"],"tags":["http","network","changelog","request-failed"],"backgroundTag":"http-non-success-status","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}