{"record":{"id":"53b3be094326c7f7","repo":"tonhowtf/omniget","slug":"not-all-segments-completed","errorCode":null,"errorMessage":"not all segments completed","messagePattern":"not all segments completed","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/http_fetcher.rs","lineNumber":567,"sourceCode":"            }\n        }\n\n        progress_pump.abort();\n        if let Some(p) = resume_pump {\n            p.abort();\n        }\n        let _ = progress_pump.await;\n\n        if let Some(e) = first_err {\n            return Err(e);\n        }\n\n        let segs = segments.lock().await;\n        let all_done = segs\n            .iter()\n            .all(|s| s.state.load(Ordering::Relaxed) == SEG_DONE);\n        if !all_done {\n            return Err(anyhow!(\"not all segments completed\"));\n        }\n        let actual = tokio::fs::metadata(part_path).await?.len();\n        if actual != total {\n            return Err(anyhow!(\n                \"size mismatch: expected {} bytes, got {}\",\n                total,\n                actual\n            ));\n        }\n\n        Ok(())\n    }\n}\n\nstruct ProbeResult {\n    content_length: Option<u64>,\n    accept_ranges: bool,\n}","sourceCodeStart":549,"sourceCodeEnd":585,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/http_fetcher.rs#L549-L585","documentation":"After all worker tasks finish, download_chunked locks the segment table and verifies every segment's state flag equals SEG_DONE. If any segment is still pending/failed/in-progress, the part file is not complete and the library refuses to proceed to assembly. This is a post-join completeness invariant for the multi-segment download.","triggerScenarios":"Worker exits without marking its segment SEG_DONE: a segment failed and the error was recorded but first_err was somehow not propagated, a worker was aborted early (cancel path), or retry bookkeeping reset a segment state after its worker ended.","commonSituations":"Cancellations racing with completion, a worker that hit a fatal error which panicking tasks masked, or state-machine bugs where a segment stays in SEG_FAILED after exhausting retries while other workers finish normally.","solutions":["Inspect the segment states logged before this error to find which segment(s) did not reach SEG_DONE and why.","Check whether first_err from worker failures was consumed earlier; make sure a failed segment always surfaces its error.","Delete the stale .part file and retry the download so all segments start fresh.","Fix the state machine so every worker exit path (success, failure, cancel) deterministically sets a terminal segment state."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// caller pattern\nif let Err(e) = download(...).await {\n    if e.to_string().contains(\"not all segments completed\") {\n        fs::remove_file(&part_path).ok(); // discard partial state, retry clean\n    }\n}","preventionTips":["Always delete the stale .part file before retrying a failed chunked download.","Ensure cancellations propagate a terminal state to every segment before joining.","Log per-segment states at the end of download_chunked to make failures diagnosable."],"tags":["download","state-machine","rust","integrity"],"backgroundTag":"invalid-state-transition","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}