github/copilot-sdk · error
failed to hash existing runtime.node
Error message
failed to hash existing runtime.node: %w
What it means
Same idempotent-skip path as the output hash: buildBundle hashes the existing runtime.node artifact with sha256FileFromCompressed and fails if reading it errors. The bundle cannot report consistent hashes without all artifact hashes, so the whole build aborts.
Solutions
- Remove the stale runtime.node artifact and rerun to force a clean download.
- Check permissions on runtimeArtifactPath.
- Ensure no other process is writing/locking the runtime file.
- Verify the output directory belongs to the same platform build (don't mix artifact sets).
- Check disk space and mount health if read errors persist.
Example fix
// before
runtimeHash, err := sha256FileFromCompressed(runtimeArtifactPath)
if err != nil {
return bundleArtifacts{}, fmt.Errorf("failed to hash existing runtime.node: %w", err)
}
// after
runtimeHash, err := sha256FileFromCompressed(runtimeArtifactPath)
if err != nil {
if os.IsNotExist(err) {
// stale artifact — fall through to re-download
} else {
return bundleArtifacts{}, fmt.Errorf("failed to hash existing runtime.node: %w", err)
}
} Defensive patterns
Strategy: try-catch
Validate before calling
for _, p := range []string{outputPath, runtimeArtifactPath, wrapperArtifactPath, assetsArtifactPath} {
f, err := os.Open(p)
if err != nil { return fmt.Errorf("artifact %s unreadable: %w", p, err) }
f.Close()
} Try / catch
artifacts, err := buildBundle(...)
if err != nil && strings.Contains(err.Error(), "runtime.node") {
os.Remove(runtimeArtifactPath) // drop stale artifact
artifacts, err = buildBundle(...) // retry
} Prevention
- Never mix artifacts from different platform builds in one output dir.
- Delete all artifacts together, never selectively.
- Check for AV/backup tools locking runtime.node in CI.
- Re-run with a clean output dir if hashes fail repeatedly.
When it happens
Trigger: filesExist passed but sha256FileFromCompressed(runtimeArtifactPath) fails — runtime.node deleted after the existence check, permission denied, corrupt/partial file from a prior interrupted run, or decompression failure inside the helper.
Common situations: Interrupted previous build left a truncated runtime.node; antivirus or backup tooling locking the file; wrong outputDir reused from a different platform build; permissions changed after first run.
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
- failed to hash existing output
- failed to hash existing runtime wrapper
- failed to hash existing runtime assets
- step(" ") journal returned a hit without a result
- Concurrent extraction race: target already exists but is…
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/d41a4c27753ab6a5.
Report an issue: GitHub.
Appendix: source
Thrown at go/cmd/bundler/main.go:420
}
runtimeArtifactPath := filepath.Join(outputDir, runtimeLibArtifactName(cliVersion, info.runtimePlatform, goos))
wrapperArtifactPath := filepath.Join(outputDir, runtimeWrapperArtifactName(cliVersion, info.runtimePlatform, info.binaryName))
assetsArtifactPath := filepath.Join(outputDir, runtimeAssetsArtifactName(cliVersion, info.runtimePlatform))
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)View on GitHub (pinned to cd8cf15dc3)