{"record":{"id":"610126f35a73add3","repo":"Billionmail/BillionMail","slug":"write-video-data-w","errorCode":null,"errorMessage":"write video data: %w","messagePattern":"write video data: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/video_gen/lipsync.go","lineNumber":190,"sourceCode":"\tresp, err := cfg.doHTTP(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"download lipsync video: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"download error %d\", resp.StatusCode)\n\t}\n\n\toutPath := filepath.Join(cfg.OutputDir, filename)\n\tf, err := os.Create(outPath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"create output file: %w\", err)\n\t}\n\tdefer f.Close()\n\n\tif _, err := io.Copy(f, resp.Body); err != nil {\n\t\treturn \"\", fmt.Errorf(\"write video data: %w\", err)\n\t}\n\n\treturn outPath, nil\n}\n","sourceCodeStart":172,"sourceCodeEnd":195,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/video_gen/lipsync.go#L172-L195","documentation":"io.Copy(f, resp.Body) failed while streaming the video bytes to disk. This means the transfer was interrupted mid-download — connection reset/timeout by the CDN or rate-limited client, or a local write error (disk full). A partial/truncated lipsync.mp4 may be left on disk since the file is not cleaned up on failure.","triggerScenarios":"Reading from resp.Body errors (connection reset, context deadline exceeded during a large download, rate-limited client cutting the connection) or writing to f errors (ENOSPC, I/O error on the mount).","commonSituations":"Large videos exceeding a proxy/LB idle timeout; context canceled mid-stream when the pipeline deadline hits; disk filling up during the copy; RateLimitedClient's 60s wait/timeout budget too small for multi-hundred-MB downloads.","solutions":["Check disk space first — a local ENOSPC surfaces here just like a network error.","Wrap the copy in an explicit context/timeout sized for the file size, or remove the tight client timeout for downloads.","Delete the partial file on error so stale truncated videos are never uploaded: os.Remove(outPath) before returning.","Compare downloaded size with Content-Length to detect truncation; retry the whole download if mismatched.","Use a buffered copy with periodic flush or resumable Range requests for very large files over flaky networks."],"exampleFix":"// before\nif _, err := io.Copy(f, resp.Body); err != nil {\n\treturn \"\", fmt.Errorf(\"write video data: %w\", err)\n}\n// after\nif _, err := io.Copy(f, resp.Body); err != nil {\n\tf.Close()\n\tos.Remove(outPath) // don't leave a truncated video on disk\n\treturn \"\", fmt.Errorf(\"write video data: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// pre-flight checks before download\nif free, err := freeDisk(cfg.OutputDir); err == nil && free < minRequiredBytes {\n\treturn fmt.Errorf(\"insufficient disk: %d bytes free\", free)\n}\nreq := http.NewRequestWithContext(ctx, \"HEAD\", videoURL, nil) // optional: check size via Content-Length","typeGuard":"func isInterruptedCopy(err error) bool {\n\treturn errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) ||\n\t\terrors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, syscall.EIO) || errors.Is(err, syscall.ENOSPC)\n}","tryCatchPattern":"path, err := DownloadLipSyncVideo(ctx, cfg, videoURL, filename)\nif err != nil && strings.Contains(err.Error(), \"write video data\") {\n\tos.Remove(filepath.Join(cfg.OutputDir, filename)) // remove partial file\n\tif isInterruptedCopy(err) { /* retry download with fresh context */ }\n\treturn err\n}","preventionTips":["Always delete the partial output file on failure so truncated videos never reach upload","Size the context/client timeout to the expected file size, not a fixed short window","Alert on disk usage in the output/tmp volumes","Verify downloaded size against Content-Length to detect silent truncation"],"tags":["network","io","download","truncated-file"],"backgroundTag":"download-interrupted","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}