{"record":{"id":"e2f552d6beac9da3","repo":"GitoxideLabs/gitoxide","slug":"cancelled-by-user-e2f552","errorCode":null,"errorMessage":"Cancelled by user","messagePattern":"Cancelled by user","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"info","filePath":"gitoxide-core/src/pack/create.rs","lineNumber":116,"sourceCode":"        statistics,\n        pack_cache_size_in_bytes,\n        object_cache_size_in_bytes,\n        mut out,\n    }: Context<W>,\n) -> anyhow::Result<()>\nwhere\n    W: std::io::Write,\n    P: NestedProgress,\n    P::SubProgress: 'static,\n{\n    type ObjectIdIter = dyn Iterator<Item = Result<ObjectId, Box<dyn std::error::Error + Send + Sync>>> + Send;\n\n    let repo = gix::discover(repository_path)?;\n    let pack_compression = repo.pack_compression()?;\n    let repo = repo.into_sync();\n    progress.init(Some(2), progress::steps());\n    let tips = tips.into_iter();\n    let make_cancellation_err = || anyhow!(\"Cancelled by user\");\n    let (mut handle, mut input): (_, Box<ObjectIdIter>) = match input {\n        None => {\n            let mut progress = progress.add_child(\"traversing\");\n            progress.init(None, progress::count(\"commits\"));\n            let tips = tips\n                .map({\n                    let easy = repo.to_thread_local();\n                    move |tip| {\n                        ObjectId::from_hex(&Vec::from_os_str_lossy(tip.as_ref())).or_else(|_| {\n                            easy.find_reference(tip.as_ref())\n                                .map_err(anyhow::Error::from)\n                                .and_then(|r| r.into_fully_peeled_id().map(gix::Id::detach).map_err(Into::into))\n                        })\n                    }\n                })\n                .collect::<Result<Vec<_>, _>>()?;\n            let handle = repo.objects.into_shared_arc().to_cache_arc();\n            let iter = Box::new(","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gitoxide-core/src/pack/create.rs#L98-L134","documentation":"During pack creation, the object-counting/writing pipeline is wrapped with gix::interrupt::Iter and uses a cancellation closure returning 'Cancelled by user'. When the process interrupt flag is set mid-pack (during traversal or object iteration), the iteration aborts with this message. It is intentional cooperative cancellation of a long-running pack write.","triggerScenarios":"Calling gitoxide_core::pack::create (public entry) with an input tip iterator and pressing Ctrl-C during commit traversal or object emission; the interrupt-aware iterator yields the error produced by make_cancellation_err.","commonSituations":"User aborting a large pack write; CI sending SIGINT/SIGTERM on timeout; interrupt flag set earlier in the process reused here.","solutions":["Expected behavior: re-run the pack creation command; partial output should be discarded.","Handle this error as a clean-cancel in callers instead of reporting a fault.","For long packs, avoid wrapping interrupt checks or run in an environment that won't signal (detached, nohup).","If cancelled spuriously, ensure only one component initializes the interrupt handler and that flags are reset between runs."],"exampleFix":"// before\nlet pack = pack::create(&repo, tips, None, &mut progress)?;\n// after\nlet pack = match pack::create(&repo, tips, None, &mut progress) {\n    Err(err) if err.to_string() == \"Cancelled by user\" => return Ok(()),\n    other => other?,\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match pack::create(&repo, tips, input, &mut progress) {\n    Err(err) if err.to_string() == \"Cancelled by user\" => return Ok(()),\n    other => other?,\n}","preventionTips":["Run long pack writes in environments that won't send SIGINT (detached/nohup).","Discard partial pack output on cancellation.","Handle cancellation as expected control flow, not an error condition."],"tags":["interrupt","cancellation","pack","user-abort"],"backgroundTag":"user-cancelled-operation","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"}