{"record":{"id":"37bd7aca5343bcb3","repo":"xtekky/gpt4free","slug":"download-interrupted-w","errorCode":null,"errorMessage":"download interrupted: %w","messagePattern":"download interrupted: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"g4f-go/download.go","lineNumber":133,"sourceCode":"\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\tout.Close()\n\t\tos.Remove(partName(binDir))\n\t\treturn fmt.Errorf(\"download failed: HTTP %s\", resp.Status)\n\t}\n\n\t// Prefer Content-Length; fall back to manifest size.\n\ttotal := resp.ContentLength\n\tif total <= 0 {\n\t\ttotal = spec.Size\n\t}\n\t_, copyErr := copyWithProgress(out, resp.Body, total, start)\n\tif cerr := out.Close(); copyErr == nil {\n\t\tcopyErr = cerr\n\t}\n\tif copyErr != nil {\n\t\tos.Remove(partName(binDir))\n\t\treturn fmt.Errorf(\"download interrupted: %w\", copyErr)\n\t}\n\tif err := os.Rename(partName(binDir), cachePath); err != nil {\n\t\tos.Remove(partName(binDir))\n\t\treturn err\n\t}\n\tfmt.Printf(\"runtime: downloaded %s in %s\\n\", humanBytes(total), time.Since(start).Round(time.Second))\n\n\tif spec.Size > 0 {\n\t\tfi, err := os.Stat(cachePath)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif fi.Size() != spec.Size {\n\t\t\treturn fmt.Errorf(\"size mismatch: got %d, expected %d (update runtime.json)\", fi.Size(), spec.Size)\n\t\t}\n\t}\n\treturn verifyRuntime(cachePath, spec)\n}","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f-go/download.go#L115-L151","documentation":"downloadRuntime in g4f-go/download.go wraps copyWithProgress failures as 'download interrupted: %w'. The response body started streaming but the read/copy failed mid-transfer (connection reset, unexpected EOF, disk full on the .part file, or write errors to binDir/.g4f-runtime/runtime.download).","triggerScenarios":"Long runtime downloads dropped mid-stream by NAT timeouts, flaky Wi-Fi, or proxy idle limits; disk full while writing the part file; the process's file descriptor or output stream (progress writer) failing.","commonSituations":"Large Python runtime archives on unstable links; mobile/tethered networks; CI runners with low disk quotas; antivirus locking the .part file on Windows.","solutions":["Free up disk space in binDir and confirm write permissions on the .g4f-runtime directory","Retry on a stable network — the partial .part file is cleaned up automatically, so the retry starts fresh","If a proxy kills idle connections, download spec.URL manually, place it at the expected cachePath (binDir/.g4f-runtime/runtime-<basename>), and re-run","Unwrap the %w cause to distinguish network resets from local write errors"],"exampleFix":"# before\n# runtime: download interrupted: unexpected EOF\n\n# after\n# manual download into the cache location the tool checks\ncurl -L -o .g4f-runtime/runtime-runtime-linux-x64.tar.gz \"<spec.URL>\"\ng4f  # reuses the cached archive","handlingStrategy":"retry","validationCode":"var stat syscall.Statfs_t\nif err := syscall.Statfs(binDir, &stat); err == nil && stat.Bavail*uint64(stat.Bsize) < uint64(spec.Size)*3 {\n    // not enough space for archive + extraction: fail fast\n}","typeGuard":null,"tryCatchPattern":"err := downloadRuntime(binDir, cachePath, spec)\nif err != nil && strings.Contains(err.Error(), \"download interrupted\") {\n    // backoff and retry; .part file is auto-cleaned so retry is safe\n}","preventionTips":["Ensure disk space for at least 3x the archive size (download + extraction)","Pre-download large runtimes on unstable links and drop them at the expected cachePath","Retry with backoff; interrupted downloads are usually transient"],"tags":["go","network","download","disk-full","retry"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}