gitbutlerapp/gitbutler · warning · anyhow::Error
Update check thread panicked
Error message
Update check thread panicked
What it means
The dedicated thread spawned for the update check panicked (or was forcibly terminated), so join() returned Err and the payload was discarded. The real panic message went to stderr; this error only says the join failed. Inside the thread, panics can come from the runtime build, the request, or response handling.
Source
Thrown at crates/but-update/src/check.rs:138
let response = client
.post(url)
.json(&request_body)
.send()
.await
.map_err(|e| anyhow::anyhow!("Request failed: {e}"))?
.error_for_status()
.map_err(|e| anyhow::anyhow!("Server returned error: {e}"))?;
let update_info = response
.json::<CheckUpdateStatus>()
.await
.map_err(|e| anyhow::anyhow!("Failed to parse response: {e}"))?;
Ok(update_info)
})
})
.join()
.map_err(|_| anyhow::anyhow!("Update check thread panicked"))?;
// Save to cache (convert to but_db types)
if let Ok(status) = &result {
let now = chrono::Utc::now();
// Get existing cache to preserve suppression
let existing = trans.update_check().get();
let (suppressed_at, suppress_duration_hours) = existing
.and_then(|cached| cached.suppressed_at.zip(cached.suppress_duration_hours))
.and_then(|(suppressed_at, duration_hours)| {
let suppress_until = suppressed_at + chrono::Duration::hours(duration_hours as i64);
if now > suppress_until {
None
} else {
Some((suppressed_at, duration_hours))
}
})
.unzip();View on GitHub (pinned to caf1f223d3)
Solutions
- Check stderr/logs for the actual panic backtrace that accompanied this error
- Update check is non-critical: catch this error and continue with cached/no update info
- If reproducible, run under a debugger or RUST_BACKTRACE=full to capture the panicking frame
- Upgrade but-update — panics in this path get fixed like any bug
Defensive patterns
Strategy: fallback
Try / catch
if let Err(e) = check_status(...) {
if e.to_string().contains("thread panicked") {
// capture stderr/backtrace in telemetry; fall back to cached status
}
} Prevention
- Always log the panic backtrace accompanying this join error — the payload here is lossy
- Make update checks fail-open (cached result, not an error dialog)
- Upgrade promptly; panics in this path are ordinary bugs that get patched
When it happens
Trigger: Any panic inside the spawned closure — e.g. a reqwest/tokio invariant, an unwrap in the caching code after join, or the thread aborted due to stack overflow/OOM kill.
Common situations: Rare; typically surfaces with a concurrent stderr panic backtrace. Aborts from OOM also manifest this way.
Related errors
- panic while executing `{}` on thread '{}' ({}) at {}: {} pa
- panic while executing `{}`: {} panic backtrace unavailable
- Failed to create runtime: {e}
- Request failed: {e}
- Server returned error: {e}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/d91b03646af817e9.
Report an issue: GitHub.