github/copilot-sdk · error

failed to hash runtime.node

Error message

failed to hash runtime.node: %w

What it means

After extracting runtime.node to the temp directory, buildBundle hashes it with sha256File for the bundle manifest. Failure to open or read the freshly extracted file is wrapped with this message and aborts the bundle. Since the file was just extracted, this usually indicates the extraction silently failed, the file was removed, or an I/O error occurred.

Solutions

  1. Verify runtime.node exists and is readable in the temp directory; re-run the build to rule out a transient race.
  2. Exclude the bundler temp directory from antivirus/on-access scanning.
  3. Set TMPDIR to a stable dedicated directory that cleanup jobs do not purge mid-build.
  4. Check disk space and dmesg for I/O errors if the failure is reproducible on reads.

Example fix

// before
TMPDIR=/tmp bundler ...
# cleaner purges /tmp mid-build

// after
mkdir -p /var/tmp/bundler-work
TMPDIR=/var/tmp/bundler-work bundler ...
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(rawLibPath)
if err != nil {
	return fmt.Errorf("runtime.node missing at %s after extraction: %w", rawLibPath, err)
}
if info.Size() < 1024 {
	return fmt.Errorf("runtime.node suspiciously small (%d bytes); extraction may be incomplete", info.Size())
}

Type guard

func fileReadable(path string) bool {
	f, err := os.Open(path)
	if err != nil {
		return false
	}
	f.Close()
	return true
}

Try / catch

if err := buildBundle(...); err != nil {
	if strings.Contains(err.Error(), "failed to hash runtime.node") {
		log.Error("runtime.node unreadable post-extract; check AV quarantine and TMPDIR cleanup")
		return err
	}
	return err
}

Prevention

When it happens

Trigger: sha256File(rawLibPath) errors on <tempDir>/runtime.node: file missing (removed by cleaner/AV), unreadable permissions, or underlying disk I/O error.

Common situations: Antivirus quarantining runtime.node immediately after extraction from the tarball, a temp-dir cleaner racing the build, or disk-full/I/O errors on a large native addon.

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/3d0da6e92205c4d1. Report an issue: GitHub.

Appendix: source

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

	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 {
		return bundleArtifacts{}, fmt.Errorf("runtime package is missing prebuilds/%s/runtime.node: %w", info.runtimePlatform, err)
	}
	runtimeHash, err := sha256File(rawLibPath)
	if err != nil {
		return bundleArtifacts{}, fmt.Errorf("failed to hash runtime.node: %w", err)
	}
	if err := compressZstdFile(rawLibPath, runtimeArtifactPath); err != nil {
		return bundleArtifacts{}, fmt.Errorf("failed to write runtime.node: %w", err)
	}

	wrapperName := runtimeWrapperName(info.binaryName)
	rawWrapperPath := filepath.Join(tempDir, wrapperName)
	if err := extractFileFromTarball(
		tarballPath,
		tempDir,
		"package/prebuilds/"+info.runtimePlatform+"/"+wrapperName,
		wrapperName,
	); err != nil {
		return bundleArtifacts{}, fmt.Errorf("runtime package is missing prebuilds/%s/%s: %w", info.runtimePlatform, wrapperName, err)
	}
	wrapperHash, err := sha256File(rawWrapperPath)
	if err != nil {
		return bundleArtifacts{}, fmt.Errorf("failed to hash runtime wrapper: %w", err)

View on GitHub (pinned to cd8cf15dc3)