github/copilot-sdk · error

failed to hash existing runtime assets

Error message

failed to hash existing runtime assets: %w

What it means

In the skip-existing path, the runtime assets artifact is hashed with sha256File (uncompressed, unlike the others); failure to read it aborts the build. Without all four hashes the bundler cannot return valid bundleArtifacts, so it fails fast.

Solutions

  1. Delete the stale assets artifact and rerun to re-download everything.
  2. Check permissions and ownership of assetsArtifactPath.
  3. Prevent concurrent jobs from cleaning the output directory mid-build.
  4. Check disk space and filesystem health.
  5. Keep all four artifacts together — never prune selectively.

Example fix

// before
assetsHash, err := sha256File(assetsArtifactPath)
if err != nil {
	return bundleArtifacts{}, fmt.Errorf("failed to hash existing runtime assets: %w", err)
}
// after
assetsHash, err := sha256File(assetsArtifactPath)
if err != nil {
	return bundleArtifacts{}, fmt.Errorf("failed to hash existing runtime assets at %s: %w", assetsArtifactPath, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

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

Try / catch

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

Prevention

When it happens

Trigger: sha256File(assetsArtifactPath) errors after filesExist reported the paths present — assets file deleted concurrently, permission denied, or unreadable/corrupt content from a prior partial run.

Common situations: Output directory partially cleaned by another job between runs; assets file corrupted by an interrupted previous build; restrictive umask or ownership change; output on a full/unstable disk.

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/525e0e65dd229af2. Report an issue: GitHub.

Appendix: source

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

	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)
	}

	if outputDir != "." {
		if err := os.MkdirAll(outputDir, 0755); err != nil {

View on GitHub (pinned to cd8cf15dc3)