github/copilot-sdk · error

failed to extract license

Error message

failed to extract license: %w

What it means

io.Copy failed while streaming the tar entry to the output file, but the subsequent outFile.Close() succeeded. The copy error typically originates from the tar/gzip reader side or a write-side failure during transfer.

Solutions

  1. Re-download the tarball and verify its checksum
  2. Test archive integrity manually (gzip -t, tar -tzf)
  3. Check free disk space on the output volume
  4. Retry the bundling operation
Defensive patterns

Strategy: try-catch

Validate before calling

if err := verifyChecksum(tarballPath, expectedSHA256); err != nil { return fmt.Errorf("tarball corrupt: %w", err) }

Try / catch

if err := extractCLILicense(tarballPath, outputDir); err != nil {
    if strings.Contains(err.Error(), "failed to extract license") {
        if err2 := verifyChecksum(tarballPath, expectedSHA256); err2 != nil { return fmt.Errorf("corrupt tarball, re-download: %w", err) }
    }
    return err
}

Prevention

When it happens

Trigger: extractFileFromTarballStream (from extractCLILicense) encounters a corrupt or truncated tarball (gzip/tar decode error mid-stream) or a disk-full/write error during the copy.

Common situations: Partially downloaded release artifact; corrupted CDN copy; interrupted decompression; full disk during bundling.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/02319334ee8663d5. Report an issue: GitHub.

Appendix: source

Thrown at go/cmd/bundler/main.go:1144

func licenseFileName(binaryName string) string {
	if strings.HasSuffix(binaryName, ".zst") {
		return strings.TrimSuffix(binaryName, ".zst") + ".license"
	}
	return binaryName + ".license"
}

// extractFileFromTarballStream writes the current tar entry to disk.
func extractFileFromTarballStream(r io.Reader, destDir, outputName string, mode os.FileMode) error {
	outPath := filepath.Join(destDir, outputName)
	outFile, err := os.OpenFile(outPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode)
	if err != nil {
		return fmt.Errorf("failed to create output file: %w", err)
	}
	if _, err := io.Copy(outFile, r); err != nil {
		if cerr := outFile.Close(); cerr != nil {
			return fmt.Errorf("failed to extract license: copy error: %v; close error: %w", err, cerr)
		}
		return fmt.Errorf("failed to extract license: %w", err)
	}
	return outFile.Close()
}

// extractFileFromTarball extracts a single file from a .tgz into destDir with a new name.
func extractFileFromTarball(tarballPath, destDir, targetPath, outputName string) error {
	file, err := os.Open(tarballPath)
	if err != nil {
		return err
	}
	defer file.Close()

	gzReader, err := gzip.NewReader(file)
	if err != nil {
		return fmt.Errorf("failed to create gzip reader: %w", err)
	}
	defer gzReader.Close()

View on GitHub (pinned to cd8cf15dc3)