gitbutlerapp/gitbutler · error
Unknown
Unknown
Error message
git fetch worker thread panicked: {reason} What it means
fetch_with_askpass runs the gix fetch on a dedicated std::thread with its own tokio runtime so askpass prompts are not blocked. If that worker thread panics (instead of returning Err), the join() payload is downcast to a reason and re-raised as this anyhow error wrapped in but_error Context 'git fetch failed unexpectedly' with Code::Unknown. It signals a bug or unrecoverable state inside the fetch stack, not a normal git failure (those come back as Err from the closure).
Source
Thrown at crates/gitbutler-git/src/context.rs:180
)?;
Ok(runtime.block_on(crate::fetch(
repo_path,
crate::tokio::TokioExecutor,
&remote,
on_prompt,
)))
})
.join()
.map_err(|panic| {
let reason = if let Some(message) = panic.downcast_ref::<String>() {
message.clone()
} else if let Some(message) = panic.downcast_ref::<&'static str>() {
(*message).to_owned()
} else {
"unknown panic payload".to_owned()
};
anyhow!("git fetch worker thread panicked: {reason}").context(
but_error::Context::new("git fetch failed unexpectedly").with_code(Code::Unknown),
)
})??;
result.map_err(map_needs_authorization)
}
/// The concrete error type produced by fetch/push through the tokio executor.
type GitError = crate::Error<crate::repository::Error<crate::tokio::TokioExecutor>>;
/// Convert the error into an anyhow error, giving `NeedsAuthorization` failures a message that
/// tells the user what to do about it (see [`needs_authorization_message`]); every other error
/// converts as-is.
fn map_needs_authorization(err: GitError) -> anyhow::Error {
let crate::Error::Backend(crate::repository::RepositoryError::NeedsAuthorization(ref prompt)) =
err
else {
return err.into();
};View on GitHub (pinned to caf1f223d3)
Solutions
- Read the embedded {reason} and the application logs — the panic message names the actual failing code
- Retry the fetch once; transient panics on concurrent .git access often clear when the other git process finishes
- Run `git fsck` and `git fetch <remote>` with the git CLI in the same worktree to surface repository corruption the panic may hint at
- Upgrade GitButler / the gix dependency — panic-on-fetch bugs are usually fixed upstream; if it persists, report an issue with the panic reason and backtrace
Defensive patterns
Strategy: retry
Try / catch
fn fetch_with_retry(ctx: &Context, remote: &str, askpass: Option<String>) -> Result<()> {
match ctx.fetch(remote, askpass.clone()) {
Ok(()) => Ok(()),
Err(first) if first.to_string().contains("fetch worker thread panicked") => {
tracing::warn!("fetch panicked, retrying once: {first}");
ctx.fetch(remote, askpass).map_err(|second| first.context(second))
}
Err(err) => Err(err),
}
} Prevention
- Avoid running concurrent git operations that mutate .git while a fetch is in flight; take the app's repository locks
- Keep the gitbutler/gix dependency current — fetch panics are usually fixed upstream
- Log the panic reason with the fetch arguments so recurring panics can be reported with reproduction data
- Run `git fsck` periodically to catch object-database corruption before it panics the fetch writer
When it happens
Trigger: Any panic inside crate::fetch / gix / tokio runtime code while fetching: index corruption, unsupported pack features hitting unwrap/expect, bugs in a specific gix version, poisoned interior state after the repo was mutated concurrently. The panic message (or 'unknown panic payload') is embedded as {reason}.
Common situations: After a gix crate upgrade introduces a panic on certain server responses; corrupted local object database making the pack writer panic; races between fetch and another process writing .git simultaneously; transient panics on malformed server data that disappear on retry.
Related errors
- Failed to find remote branch's corresponding remote
- failed to find branch {target_branch_refname}
- failed to determine remote and branch name for `{branch}`
- repo access failed
- Failed to communicate with LM Studio server: ${error instanc
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/7a6e2b2dc4772a98.
Report an issue: GitHub.