GitoxideLabs/gitoxide · error

rebase worker panicked

Error message

rebase worker panicked

What it means

After the rebase driver loop finishes, the worker thread's `JoinHandle::join()` is checked; a join error means the worker thread panicked rather than returned normally. The panic itself is discarded, so only this generic message is reported to the user.

Solutions

  1. Capture the panic payload: `match worker.join() { Err(p) => report {:?} of p, ... }` so the real panic message is shown instead of a generic one.
  2. Run the operation with `RUST_BACKTRACE=1` and reproduce to find the panicking call site in the worker closure.
  3. Replace `unwrap()`/`expect()` in the worker closure with error propagation via the `Complete(Err(...))` event.
  4. Check the repository state (corrupt objects, malformed rebase todo) that may trigger the panic path.

Example fix

// before
if worker.join().is_err() {
    return Err(anyhow::anyhow!("rebase worker panicked"));
}
// after
if let Err(panic) = worker.join() {
    return Err(anyhow::anyhow!("rebase worker panicked: {panic:?}"));
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Cannot validate ahead of time; enable panic capture in the worker closure:
let worker = thread::spawn(move || std::panic::catch_unwind(AssertUnwindSafe(worker_body)));

Type guard

fn worker_panicked(join: &Result<(), Box<dyn Any + Send>>) -> bool {
    join.is_err()
}

Try / catch

match worker.join() {
    Err(panic) => Err(anyhow::anyhow!("rebase worker panicked: {panic:?}")),
    Ok(Err(e)) => Err(e),
    Ok(Ok(v)) => Ok(v),
}

Prevention

When it happens

Trigger: The closure passed to the rebase worker thread panicked (e.g. `unwrap()`/index-out-of-bounds inside rebase execution) and `worker.join()` returned `Err` at gix-tix/src/lib.rs:5867.

Common situations: A panic in gix internals triggered by an unusual repository state (corrupt object, bad todo line); a bug such as an out-of-range index while rendering/processing todos; an `expect()` firing in the worker.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/43490a4f0baec2b8. Report an issue: GitHub.

Appendix: source

Thrown at gix-tix/src/lib.rs:5867

                Some(RebaseWorkerEvent::Progress(progress)) => latest = Some(progress),
                Some(RebaseWorkerEvent::Complete(result)) => break result,
                None => {}
            }
            let now = Instant::now();
            if todo_progress_visible(now.duration_since(started))
                && latest != rendered
                && now.duration_since(last_draw) >= FRAME_INTERVAL
            {
                let progress = latest.expect("a changed progress snapshot is available");
                if let Err(err) = terminal.draw(|frame| ui::draw_todo_progress(frame, progress)) {
                    break Err(err).context("could not draw rebase progress");
                }
                rendered = latest;
                last_draw = now;
            }
        };
        if worker.join().is_err() {
            return Err(anyhow::anyhow!("rebase worker panicked"));
        }
        result
    })
}

fn todo_progress_visible(elapsed: Duration) -> bool {
    elapsed >= TODO_PROGRESS_DELAY
}

#[derive(Clone, Copy)]
enum CreateMode {
    Insert,
    InsertEmpty,
    Fork,
}

#[tracing::instrument(skip_all, fields(parent = ?parent, fork = matches!(mode, CreateMode::Fork)))]
fn create_commit(

View on GitHub (pinned to e73179060b)