{"record":{"id":"be2cc28c03a30071","repo":"github/copilot-sdk","slug":"failed-to-extract-license-copy-error-v-close-e","errorCode":null,"errorMessage":"failed to extract license: copy error: %v; close error: %w","messagePattern":"failed to extract license: copy error: (.+?); close error: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/cmd/bundler/main.go","lineNumber":1142,"sourceCode":"}\n\nfunc licenseFileName(binaryName string) string {\n\tif strings.HasSuffix(binaryName, \".zst\") {\n\t\treturn strings.TrimSuffix(binaryName, \".zst\") + \".license\"\n\t}\n\treturn binaryName + \".license\"\n}\n\n// extractFileFromTarballStream writes the current tar entry to disk.\nfunc extractFileFromTarballStream(r io.Reader, destDir, outputName string, mode os.FileMode) error {\n\toutPath := filepath.Join(destDir, outputName)\n\toutFile, err := os.OpenFile(outPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create output file: %w\", err)\n\t}\n\tif _, err := io.Copy(outFile, r); err != nil {\n\t\tif cerr := outFile.Close(); cerr != nil {\n\t\t\treturn fmt.Errorf(\"failed to extract license: copy error: %v; close error: %w\", err, cerr)\n\t\t}\n\t\treturn fmt.Errorf(\"failed to extract license: %w\", err)\n\t}\n\treturn outFile.Close()\n}\n\n// extractFileFromTarball extracts a single file from a .tgz into destDir with a new name.\nfunc extractFileFromTarball(tarballPath, destDir, targetPath, outputName string) error {\n\tfile, err := os.Open(tarballPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n\n\tgzReader, err := gzip.NewReader(file)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create gzip reader: %w\", err)\n\t}","sourceCodeStart":1124,"sourceCodeEnd":1160,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/cmd/bundler/main.go#L1124-L1160","documentation":"During io.Copy of the tar entry into the output file, the copy failed AND the deferred cleanup call to outFile.Close() also returned an error. Both the original copy error and the close error are embedded in the message so neither root cause is lost.","triggerScenarios":"extractFileFromTarballStream (from extractCLILicense) hits a read failure on the tar/gzip stream (corrupt tarball, truncated download, decompression error) or a write failure (disk full) while closing the partially written file also fails.","commonSituations":"Interrupted/partial download of the CLI tarball; corrupted gzip data; disk quota exhausted mid-write; NFS/network volume flakiness.","solutions":["Re-download or re-fetch the tarball to rule out corruption/truncation","Check disk space and quotas on the output filesystem","Fix the close error cause (permissions, I/O errors) reported after the '; close error:' part","Verify the tarball integrity (checksum) before extraction"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if err := verifyChecksum(tarballPath, expectedSHA256); err != nil { return fmt.Errorf(\"tarball corrupt before extraction: %w\", err) }\nif free, err := diskFree(outputDir); err == nil && free < minRequiredBytes { return fmt.Errorf(\"insufficient disk space\") }","typeGuard":null,"tryCatchPattern":"if err := extractCLILicense(tarballPath, outputDir); err != nil {\n    var cw combinedWriteError\n    if errors.As(err, &cw) { log.Printf(\"copy: %v, close: %v\", cw.CopyErr, cw.CloseErr) }\n    return err\n}","preventionTips":["Verify checksums of downloaded artifacts before extraction","Ensure adequate free disk space before bundling","Re-download rather than retry on corrupted archives","Avoid extraction onto flaky network filesystems"],"tags":["go","io","corruption","disk-full"],"backgroundTag":"file-write-failed","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}