gitbutlerapp/gitbutler · error · anyhow::Error

Failed to join thread: {e:?}

Error message

Failed to join thread: {e:?}

What it means

To fetch GitHub CI checks synchronously, but-forge spawns a thread that builds a tokio runtime and calls but_github::checks::list_for_ref. join() returned Err, meaning that thread panicked; the error embeds the panic payload's Debug output. Note the thread body uses Runtime::new().unwrap(), so tokio runtime creation failure is one concrete panic source inside that thread.

Source

Thrown at crates/but-forge/src/ci.rs:119

            let owner = owner.clone();
            let repo = repo.clone();
            let storage = storage.clone();
            let reference = reference.to_string();
            let reference_for_checks = reference.clone();

            let checks = std::thread::spawn(move || {
                tokio::runtime::Runtime::new()
                    .unwrap()
                    .block_on(but_github::checks::list_for_ref(
                        preferred_account.as_ref(),
                        &owner,
                        &repo,
                        &reference,
                        &storage,
                    ))
            })
            .join()
            .map_err(|e| anyhow::anyhow!("Failed to join thread: {e:?}"))?;
            checks.map(|maybe_runs| {
                maybe_runs.map(|runs| {
                    runs.into_iter()
                        .map(|check| {
                            let mut ci_check = CiCheck::from(check);
                            ci_check.reference = reference_for_checks.to_string();
                            ci_check
                        })
                        .collect()
                })
            })
        }
        ForgeName::GitLab => {
            let preferred_account = preferred_forge_user
                .as_ref()
                .and_then(|user| user.gitlab().cloned());
            let gl = but_gitlab::GitLabClient::from_storage(storage, preferred_account.as_ref())?;

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Inspect the {e:?} payload in the message - it names the panic reason
  2. If it mentions runtime or io creation errors, raise ulimits (threads, fds) for the application process
  3. Otherwise capture the panic output and report it upstream with the forge, owner/repo and ref
Defensive patterns

Strategy: fallback

Try / catch

match list_ci_checks(&forge, owner, repo, reference) {
    Err(err) if err.to_string().contains("Failed to join thread") => {
        // render CI status as 'unavailable' and keep the rest of the PR view working
    }
    result => result,
}

Prevention

When it happens

Trigger: Any panic inside the GitHub checks thread: Runtime::new().unwrap() failing under resource pressure (thread/fd limits), or a bug in the checks listing or CiCheck mapping code.

Common situations: Sandboxed desktop environments or containers with low thread/file-descriptor ulimits; regressions in the GitHub checks response mapping.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/40ce79f3132fb76f. Report an issue: GitHub.