github/copilot-sdk · error

failed to hash existing runtime wrapper

Error message

failed to hash existing runtime wrapper: %w

What it means

In the skip-existing path of buildBundle, the runtime wrapper artifact is hashed with sha256FileFromCompressed; failure to read it aborts the build. All artifacts must hash successfully for the bundle to be considered valid and reusable.

Solutions

  1. Delete stale wrapper artifacts and rerun the bundler.
  2. Check permissions on wrapperArtifactPath.
  3. Serialize builds so only one bundler run owns the output directory.
  4. Exclude the output dir from concurrent clean/AV jobs.
  5. If only the wrapper is bad, restoring just that artifact avoids a full rebuild.

Example fix

// before
wrapperHash, err := sha256FileFromCompressed(wrapperArtifactPath)
if err != nil {
	return bundleArtifacts{}, fmt.Errorf("failed to hash existing runtime wrapper: %w", err)
}
// after
wrapperHash, err := sha256FileFromCompressed(wrapperArtifactPath)
if err != nil {
	return bundleArtifacts{}, fmt.Errorf("failed to hash existing runtime wrapper at %s: %w", wrapperArtifactPath, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

f, err := os.Open(wrapperArtifactPath)
if err != nil {
	return fmt.Errorf("wrapper artifact unreadable: %w", err)
}
f.Close()

Try / catch

artifacts, err := buildBundle(...)
if err != nil && strings.Contains(err.Error(), "runtime wrapper") {
	os.RemoveAll(outputDir)
	artifacts, err = buildBundle(...) // full clean rebuild
}

Prevention

When it happens

Trigger: sha256FileFromCompressed(wrapperArtifactPath) errors after filesExist reported all paths present — wrapper file removed concurrently, unreadable permissions, or corrupt/partial content from an earlier interrupted run.

Common situations: Concurrent build/clean racing on the same output dir; wrapper file truncated by a previous crash; output dir on an unreliable network share; permission changes by tooling between runs.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

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

	requiredPaths := []string{outputPath, runtimeArtifactPath, wrapperArtifactPath, assetsArtifactPath}
	if includeLicense {
		requiredPaths = append(requiredPaths, licensePathForOutput(outputPath))
	}

	if filesExist(requiredPaths...) {
		// Idempotent output avoids re-downloading in CI or local rebuilds.
		fmt.Printf("Output runtime bundle for %s already exists, skipping download\n", info.runtimePlatform)
		binaryHash, err := sha256FileFromCompressed(outputPath)
		if err != nil {
			return bundleArtifacts{}, fmt.Errorf("failed to hash existing output: %w", err)
		}
		runtimeHash, err := sha256FileFromCompressed(runtimeArtifactPath)
		if err != nil {
			return bundleArtifacts{}, fmt.Errorf("failed to hash existing runtime.node: %w", err)
		}
		wrapperHash, err := sha256FileFromCompressed(wrapperArtifactPath)
		if err != nil {
			return bundleArtifacts{}, fmt.Errorf("failed to hash existing runtime wrapper: %w", err)
		}
		assetsHash, err := sha256File(assetsArtifactPath)
		if err != nil {
			return bundleArtifacts{}, fmt.Errorf("failed to hash existing runtime assets: %w", err)
		}
		return bundleArtifacts{outputPath, binaryHash, runtimeArtifactPath, runtimeHash, wrapperArtifactPath, wrapperHash, assetsArtifactPath, assetsHash}, nil
	}

	// Create temp directory for download
	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)

View on GitHub (pinned to cd8cf15dc3)