GitoxideLabs/gitoxide · error · anyhow::Error

history refresh worker stopped unexpectedly

Error message

history refresh worker stopped unexpectedly

What it means

Runtime guard in gix-tix's TUI event loop for the history-refresh worker. Refreshes (re-reading refs, decorations, worktree head state) run off-thread and deliver results over a channel; if the receiver finds the channel closed without a result, the refresh worker died unexpectedly and the pending history refresh cannot complete. The UI would otherwise wait forever for decorations and selection relation updates, so the failure is surfaced. Indicates a worker-thread panic/early exit; recover by restarting the app or issuing another refresh.

Solutions

  1. Look for the underlying panic message from the refresh worker thread in stderr/tracing, since this error only signals that its channel closed
  2. Verify the repository is readable and not concurrently locked or deleted, then restart tix to relaunch the history refresh
  3. Capture a backtrace of the panicking worker (RUST_BACKTRACE=1) and report it if the crash is reproducible
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at gix-tix/src/lib.rs:1616 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

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

                            .and_then(|repo| Ok(repo.head()?.is_unborn()))
                            .unwrap_or(false);
                    app.set_worktree_head_unborn(worktree_head_unborn);
                    decorations = result.decorations;
                    selection_relation = None;
                    app.selection_relation = None;
                    let hidden_tips = if app.show_hidden {
                        &[][..]
                    } else {
                        result.refs.hidden_tips.as_slice()
                    };
                    if let Some(rows) = app.start_refresh(result.commits, &result.refs.view_tips, hidden_tips, false) {
                        lane_receiver = Some(start_lane_worker(rows));
                    }
                    refresh_receiver = None;
                    dirty = true;
                }
                Err(mpsc::TryRecvError::Empty) => {}
                Err(mpsc::TryRecvError::Disconnected) => anyhow::bail!("history refresh worker stopped unexpectedly"),
            }
        }
        if ref_tree_refresh_pending
            && refresh_receiver.is_none()
            && lane_receiver.is_none()
            && history_graph.is_some()
            && matches!(app.state, State::Complete | State::Cancelled)
        {
            ref_tree_refresh_pending = false;
            refresh_receiver = Some(start_history_refresh(
                repository_path.clone(),
                repository_is_bare,
                revisions.clone(),
                if app.show_hidden { Vec::new() } else { hide.clone() },
                true,
                Default::default(),
                gix::features::threading::OwnShared::clone(&authors),
                history_graph

View on GitHub (pinned to e73179060b)