{"record":{"id":"2f999f7bb705152d","repo":"apache/beam","slug":"error-in-coping-file-s-inside-jar-s-w","errorCode":null,"errorMessage":"error in coping file %s inside jar %s: %w","messagePattern":"error in coping file (.+?) inside jar (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/xlangx/expansionx/download.go","lineNumber":136,"sourceCode":"\n\tresp, err := http.Get(string(url))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != 200 {\n\t\treturn \"\", fmt.Errorf(\"failed to connect to %v: received non 200 response code, got %v\", url, resp.StatusCode)\n\t}\n\n\tfile, err := os.Create(jarPath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error in creating jar %s: %w\", jarPath, err)\n\t}\n\n\t_, err = io.Copy(file, resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error in coping file %s inside jar %s: %w\", file.Name(), jarPath, err)\n\t}\n\n\treturn jarPath, nil\n}\n\nfunc validatePath(dest, filename string) (string, error) {\n\tdestPath := filepath.Join(dest, filename)\n\tcleanDest := filepath.Clean(dest)\n\tcleanPath := filepath.Clean(destPath)\n\n\trel, err := filepath.Rel(cleanDest, cleanPath)\n\tif err != nil || strings.HasPrefix(rel, \"..\"+string(filepath.Separator)) || rel == \"..\" {\n\t\treturn \"\", fmt.Errorf(\"file path %q is outside destination directory %q\", filename, dest)\n\t}\n\treturn cleanPath, nil\n}\n\nfunc extractJar(source, dest string) error {","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/xlangx/expansionx/download.go#L118-L154","documentation":"getLocalJar streams the HTTP response body into the freshly created jar file with io.Copy. This error is returned when that copy fails mid-stream — the connection dropped, the server closed the connection early, or a read/write I/O error occurred. The result is a truncated jar, so the library aborts instead of returning a partial file path.","triggerScenarios":"io.Copy(file, resp.Body) returns non-nil during getLocalJar: network interruption, proxy timeout on large jars, or disk filling up during the write.","commonSituations":"Downloading the large Java expansion service jar over flaky corporate Wi-Fi; a proxy that kills long-lived connections; CI with a small tmpfs that fills while copying.","solutions":["Retry the download; transient network failures are the most common cause.","Check free disk space on the destination filesystem.","Pre-download the jar with curl/wget (which support resume) and place it at the expected jarPath.","Use a more stable network or a local artifact mirror."],"exampleFix":"// before\n// single attempt download\n// after\nvar jarPath string\nvar err error\nfor i := 0; i < 3; i++ {\n    jarPath, err = expansionx.MakeJar(ctx, url, dest)\n    if err == nil { break }\n    time.Sleep(time.Duration(1<<i) * time.Second)\n}","handlingStrategy":"retry","validationCode":"if fi, err := os.Stat(destDir); err != nil || !fi.IsDir() {\n    return fmt.Errorf(\"destination %s unusable\", destDir)\n}\n// also confirm the URL is reachable so a long download is worthwhile\nresp, err := http.Head(url)\nif err != nil || resp.StatusCode != 200 { return fmt.Errorf(\"url unreachable\") }","typeGuard":null,"tryCatchPattern":"var jarPath string\nvar err error\nfor attempt := 0; attempt < 3; attempt++ {\n    jarPath, err = expansionx.MakeJar(ctx, url, dest)\n    if err == nil { break }\n    time.Sleep(time.Duration(1<<attempt) * time.Second)\n}","preventionTips":["Use stable networks or internal mirrors for large jar downloads.","Configure proxies to allow long-lived connections for big artifacts.","Pre-download the jar and place it at the expected path to skip the network copy.","Ensure adequate free disk space before downloads."],"tags":["go","io","network","download"],"backgroundTag":"file-write-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}