{"record":{"id":"6b19350c62c6bd1c","repo":"GitoxideLabs/gitoxide","slug":"time-travel-worker-panicked","errorCode":null,"errorMessage":"time-travel worker panicked","messagePattern":"time-travel worker panicked","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/lib.rs","lineNumber":5790,"sourceCode":"                    std::thread::sleep(FRAME_INTERVAL.saturating_sub(last_draw.elapsed()));\n                }\n                let id = latest.expect(\"a changed rebased commit is available\");\n                if let Err(err) = render(id) {\n                    render_error = Some(err);\n                    continue;\n                }\n                rendered = latest;\n                last_draw = Some(Instant::now());\n            }\n            if let Some(result) = complete.take() {\n                break result;\n            }\n        };\n        if let Some(err) = render_error {\n            tracing::warn!(error = %err, \"time-travel animation stopped\");\n        }\n        if worker.join().is_err() {\n            return Err(anyhow::anyhow!(\"time-travel worker panicked\"));\n        }\n        result\n    })\n}\n\nfn run_rebase_plan(\n    terminal: &mut ratatui::DefaultTerminal,\n    repository: gix::ThreadSafeRepository,\n    graph: &HistoryGraph,\n    plan: edit::rebase::Plan,\n) -> Result<edit::rebase::PlanPerform> {\n    run_with_todo_progress(terminal, move |report| {\n        let mut repository = repository.to_thread_local();\n        repository.object_cache_size(None);\n        edit::rebase::perform_plan_with_progress(&repository, graph, plan, report)\n    })\n}\n","sourceCodeStart":5772,"sourceCodeEnd":5808,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/lib.rs#L5772-L5808","documentation":"After the time-travel animation finishes, the main thread calls `worker.join()`; if the JoinHandle returns `Err` (the worker thread panicked), the animation wrapper converts it to this error instead of propagating the panic payload.","triggerScenarios":"`worker.join()` returns `Err(_)` — the time-travel render/rebase worker thread panicked (e.g. an unwrap/index panic in the animation or rebase-plan code running on that thread).","commonSituations":"A panic inside worker-side rendering code (bad frame math), object lookups that panic on missing objects, or any `unwrap()` in the worker body triggered by unusual repository state during time-travel animation.","solutions":["Find the underlying panic: capture the JoinError payload (`err.into_panic()`) and downcast to `&str`/`String` to log the real message and backtrace.","Fix the panicking code in the worker (replace unwraps with error propagation).","Optionally run the worker body under `std::panic::catch_unwind` and report the panic as a normal error event over the channel."],"exampleFix":"// before\nif worker.join().is_err() {\n    return Err(anyhow::anyhow!(\"time-travel worker panicked\"));\n}\n// after\nif let Err(join_err) = worker.join() {\n    let msg = join_err.downcast_ref::<String>().cloned()\n        .or_else(|| join_err.downcast_ref::<&str>().map(|s| s.to_string()))\n        .unwrap_or_else(|| \"unknown panic\".into());\n    return Err(anyhow::anyhow!(\"time-travel worker panicked: {msg}\"));\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight: run the worker logic on a sample repo to surface panics early\nworker_smoke_test(&repo).expect(\"time-travel worker logic should not panic\");","typeGuard":"fn panic_message(e: std::boxed::Box<dyn std::any::Any + Send>) -> String {\n    e.downcast_ref::<String>().cloned()\n        .or_else(|| e.downcast_ref::<&str>().map(|s| s.to_string()))\n        .unwrap_or_else(|| \"unknown panic\".into())\n}","tryCatchPattern":"match worker.join() {\n    Ok(v) => v,\n    Err(payload) => return Err(anyhow::anyhow!(\"time-travel worker panicked: {}\", panic_message(payload))),\n}","preventionTips":["Replace `unwrap()` in worker code with error propagation.","Run the animation/rebase worker body under `catch_unwind` and report via the event channel.","Add panic hooks with backtraces to diagnose worker panics quickly."],"tags":["panic","worker-thread","join","ui"],"backgroundTag":"worker-thread-panicked","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}