github/copilot-sdk · error

opening runtime assets

Error message

opening runtime assets: %w

What it means

After hash verification, installRuntimeAssets opens the archive bytes as a gzip stream with gzip.NewReader. Failure is wrapped as "opening runtime assets". This means the bytes are not valid gzip data.

Solutions

  1. Verify the archive is gzip (file runtime.tar.gz / gzip -t)
  2. Re-download or re-embed the correct .tar.gz asset
  3. Check the download source isn't returning HTML/error bodies (log first bytes on failure)
  4. Confirm RuntimeAssetsHash was computed over the same gzip archive being supplied

Example fix

// before
resp, _ := http.Get(url)
cfg.RuntimeAssets = resp.Body // may be an error page
// after
if resp.StatusCode != http.StatusOK {
    return fmt.Errorf("download failed: %s", resp.Status)
}
cfg.RuntimeAssets = resp.Body
Defensive patterns

Strategy: validation

Validate before calling

archive, _ := io.ReadAll(src)
if len(archive) < 2 || archive[0] != 0x1f || archive[1] != 0x8b {
    return fmt.Errorf("not a gzip archive (first bytes: %q)", archive[:min(16, len(archive))])
}

Type guard

func isGzip(b []byte) bool { return len(b) >= 2 && b[0] == 0x1f && b[1] == 0x8b }

Try / catch

err := embeddedcli.InstallRuntime(ctx, cfg, dir)
if err != nil && strings.Contains(err.Error(), "opening runtime assets") {
    return fmt.Errorf("runtime asset is not valid gzip: verify download source returned the archive, not an error page")
}

Prevention

When it happens

Trigger: gzip.NewReader(bytes.NewReader(archiveBytes)) returns a header error: the asset is a plain tar (not .tar.gz), an HTML error page from a failed download, or a corrupt/truncated gzip file.

Common situations: CI artifact upload mislabeled or corrupted; a download URL returning an error page that was saved as the archive; packaging the wrong (uncompressed) file.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at go/internal/embeddedcli/embeddedcli.go:380

func installRuntimeAssets(installDir string) error {
	if config.RuntimeAssets == nil || runtimeAssetsInstalled {
		return nil
	}
	archiveBytes, err := io.ReadAll(config.RuntimeAssets)
	if closer, ok := config.RuntimeAssets.(io.Closer); ok {
		closer.Close()
	}
	if err != nil {
		return fmt.Errorf("reading runtime assets: %w", err)
	}
	actual := sha256.Sum256(archiveBytes)
	if !bytes.Equal(actual[:], config.RuntimeAssetsHash) {
		return fmt.Errorf("runtime assets hash mismatch")
	}
	gzipReader, err := gzip.NewReader(bytes.NewReader(archiveBytes))
	if err != nil {
		return fmt.Errorf("opening runtime assets: %w", err)
	}
	defer gzipReader.Close()
	tarReader := tar.NewReader(gzipReader)
	for {
		header, err := tarReader.Next()
		if err == io.EOF {
			break
		}
		if err != nil {
			return fmt.Errorf("reading runtime assets: %w", err)
		}
		if header.Typeflag != tar.TypeReg {
			continue
		}
		clean := filepath.Clean(filepath.FromSlash(header.Name))
		if !filepath.IsLocal(clean) {
			return fmt.Errorf("unsafe runtime asset path %q", header.Name)
		}

View on GitHub (pinned to cd8cf15dc3)