gitbutlerapp/gitbutler · error

Failed fetch review : failed to create Tokio runtime

Error message

Failed fetch review {review_number}: failed to create Tokio runtime: {e}

What it means

This error wraps the failure of `tokio::runtime::Runtime::new()` when `get_forge_review` spawns a dedicated OS thread to run an async forge-review fetch via `block_on`. Tokio runtime creation can only fail in restricted environments (e.g. resource limits preventing thread or socket-pool creation), and this message surfaces that low-level cause with the review number attached. It means the review fetch never even started because no async executor could be built.

Solutions

  1. Check and raise the OS thread limit (ulimit -u / container pids limit) on the machine running the tool.
  2. Free memory or increase the memory available to the process/container.
  3. Retry the operation once resources are freed; the failure is environmental, not caused by the review number.
  4. If embedding, avoid calling from an environment with per-thread restrictions or reduce concurrent fetch operations.

Example fix

// before
let runtime = tokio::runtime::Runtime::new().map_err(|e| {
    anyhow::anyhow!("Failed fetch review {review_number}: failed to create Tokio runtime: {e}")
})?;

// after: verify thread limits first, e.g. on Linux
// ulimit -u 4096   (raise the user process/thread limit)
// or in a container: --pids-limit=4096
let runtime = tokio::runtime::Runtime::new().map_err(|e| {
    anyhow::anyhow!("Failed fetch review {review_number}: failed to create Tokio runtime: {e}")
})?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: rough resource pre-check before spawning
let ok = std::thread::available_parallelism().is_ok();
if !ok { eprintln!("thread limits may block runtime creation"); }

Try / catch

match get_forge_review(...) {
    Ok(review) => use(review),
    Err(e) if e.to_string().contains("failed to create Tokio runtime") => {
        // environmental failure: raise thread limits / free memory, then retry once
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `get_forge_review` on a system where `Runtime::new()` fails: the process has exhausted the ability to spawn threads (RLIMIT_NPROC / ulimit -u hit), insufficient memory for the runtime's blocking pool, or running inside a sandbox/container with restricted thread creation.

Common situations: CI containers with low thread limits; heavily loaded machines at the process/thread limit; memory-constrained environments; embedding the library in a process that already spawns many threads per operation.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/497c567f86c7c61d. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-forge/src/review.rs:2335

}

/// Get a specific review (e.g. pull request) for a given forge repository
///
/// The resulting review will be cached.
pub fn get_forge_review(
    preferred_forge_user: &Option<crate::ForgeUser>,
    forge_repo_info: &crate::forge::ForgeRepoInfo,
    review_number: usize,
    db: &mut but_db::DbHandle,
    storage: &but_forge_storage::Controller,
) -> Result<ForgeReview> {
    let preferred_forge_user = preferred_forge_user.clone();
    let forge_repo_info = forge_repo_info.clone();
    let storage = storage.clone();

    let review = std::thread::spawn(move || {
        let runtime = tokio::runtime::Runtime::new().map_err(|e| {
            anyhow::anyhow!(
                "Failed fetch review {review_number}: failed to create Tokio runtime: {e}"
            )
        })?;

        runtime.block_on(get_forge_review_inner(
            &preferred_forge_user,
            &forge_repo_info,
            review_number,
            &storage,
        ))
    })
    .join()
    .map_err(|e| {
        anyhow::anyhow!("Failed to fetch review {review_number}: thread panicked: {e:?}")
    })??;

    // Cache the review and ignore any issues, if any.
    crate::db::upsert_review(db, &review).ok();

View on GitHub (pinned to 58e5313667)