github/copilot-sdk · error

failed to extract CLI license

Error message

failed to extract CLI license: %w

What it means

When includeLicense is set, buildBundle calls extractCLILicense to pull the license file out of the downloaded CLI tarball and write it next to the output. Any failure inside that extraction (reading the tarball, locating the license entry, writing the destination) is wrapped with this message and aborts the bundle.

Solutions

  1. Delete the cached/downloaded tarball and re-download it (verify its size/checksum) to rule out a corrupt archive.
  2. Confirm the CLI package version still contains the license file at the path extractCLILicense expects; check archive contents with tar -tf.
  3. Retry the bundle without --include-license if licensing output is not required for your build.
  4. Ensure outputPath is writable and not occupied by a read-only file.

Example fix

// before
rm -rf ~/.cache/bundler/cli-*.tgz
bundler --include-license ...
// fails on corrupt tarball

// after
rm -rf ~/.cache/bundler/cli-*.tgz   # force clean re-download
bundler --include-license ...
Defensive patterns

Strategy: try-catch

Validate before calling

f, err := os.Open(tarballPath)
if err != nil {
	return fmt.Errorf("tarball unreadable: %w", err)
}
defer f.Close()
gr, err := gzip.NewReader(f)
if err != nil {
	return fmt.Errorf("tarball not valid gzip (likely corrupt/truncated): %w", err)
}
gr.Close()

Type guard

func tarballHasEntry(tarballPath, name string) bool {
	f, err := os.Open(tarballPath)
	if err != nil {
		return false
	}
	defer f.Close()
	gz, err := gzip.NewReader(f)
	if err != nil {
		return false
	}
	defer gz.Close()
	tr := tar.NewReader(gz)
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			return false
		}
		if err != nil {
			return false
		}
		if filepath.Clean(hdr.Name) == filepath.Clean(name) {
			return true
		}
	}
}

Try / catch

if err := buildBundle(...); err != nil {
	if strings.Contains(err.Error(), "failed to extract CLI license") {
		log.Warn("license extraction failed; re-downloading tarball and retrying without license")
	}
	return err
}

Prevention

When it happens

Trigger: extractCLILicense(tarballPath, outputPath) errors: the tarball is corrupt/truncated, the expected license file is absent from the archive, or the destination path cannot be written.

Common situations: A partially downloaded or checksum-invalid tarball (interrupted download, proxy interference), a CLI package version whose archive layout no longer contains the license at the expected path, or an output location that became unwritable between steps.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

	tempDir, err := os.MkdirTemp("", "copilot-bundler-*")
	if err != nil {
		return bundleArtifacts{}, fmt.Errorf("failed to create temp dir: %w", err)
	}
	defer os.RemoveAll(tempDir)

	binaryPath, tarballPath, err := downloadCLIBinary(info.runtimePlatform, info.binaryName, cliVersion, tempDir)
	if err != nil {
		return bundleArtifacts{}, fmt.Errorf("failed to download CLI binary: %w", err)
	}

	if outputDir != "." {
		if err := os.MkdirAll(outputDir, 0755); err != nil {
			return bundleArtifacts{}, fmt.Errorf("failed to create output directory: %w", err)
		}
	}
	if includeLicense {
		if err := extractCLILicense(tarballPath, outputPath); err != nil {
			return bundleArtifacts{}, fmt.Errorf("failed to extract CLI license: %w", err)
		}
	}

	binaryHash, err := sha256File(binaryPath)
	if err != nil {
		return bundleArtifacts{}, fmt.Errorf("failed to hash output binary: %w", err)
	}
	if err := compressZstdFile(binaryPath, outputPath); err != nil {
		return bundleArtifacts{}, fmt.Errorf("failed to write output binary: %w", err)
	}

	rawLibPath := filepath.Join(tempDir, "runtime.node")
	if err := extractFileFromTarball(
		tarballPath,
		tempDir,
		"package/prebuilds/"+info.runtimePlatform+"/runtime.node",
		"runtime.node",
	); err != nil {

View on GitHub (pinned to cd8cf15dc3)