github/copilot-sdk · error
failed to hash existing output
Error message
failed to hash existing output: %w
What it means
When the bundle output already exists (idempotent-skip path), buildBundle hashes the existing binary with sha256FileFromCompressed to report/verify integrity. This error wraps any failure reading or hashing that existing output file — typically the file is missing, unreadable, or corrupted mid-write from a previous failed run.
Solutions
- Delete the stale output artifacts and rerun the bundler so it re-downloads fresh.
- Check file permissions on the output path.
- Verify no concurrent process deletes/moves files in the output directory.
- Check disk health / mount stability if I/O errors persist.
- Run the bundler with exclusive access to the output directory.
Example fix
// before
binaryHash, err := sha256FileFromCompressed(outputPath)
if err != nil {
return bundleArtifacts{}, fmt.Errorf("failed to hash existing output: %w", err)
}
// after
binaryHash, err := sha256FileFromCompressed(outputPath)
if err != nil {
fmt.Printf("Existing output unreadable (%v), rebuilding\n", err)
// fall through to full download path instead of failing
} Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := os.Open(outputPath); err != nil {
// treat cache as invalid; force full rebuild
}
fi, _ := os.Stat(outputPath)
if fi != nil && fi.Size() == 0 {
// zero-length artifact from an interrupted run — rebuild
} Try / catch
artifacts, err := buildBundle(...)
if err != nil && strings.HasPrefix(err.Error(), "failed to hash existing output") {
os.Remove(outputPath) // clear stale cache
artifacts, err = buildBundle(...) // retry once
} Prevention
- Run the bundler with exclusive access to the output directory.
- Treat existence-check + hash as atomic; rebuild if hashing fails.
- Clean stale artifacts after interrupted builds (trap signals in CI).
- Avoid output dirs on unreliable network mounts.
When it happens
Trigger: filesExist(requiredPaths...) returned true, but sha256FileFromCompressed(outputPath) fails — file deleted between the existence check and the hash, permission denied, or an I/O error reading the partially-written artifact.
Common situations: A previous bundler run was killed mid-download leaving a stale/locked file; output file removed by a concurrent clean job; read permissions changed; output on a flaky/network mount.
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 runtime.node
- 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/d4a4231f534449f5.
Report an issue: GitHub.
Appendix: source
Thrown at go/cmd/bundler/main.go:416
func buildBundle(info platformInfo, cliVersion, outputPath, goos string, includeLicense bool) (bundleArtifacts, error) {
outputDir := filepath.Dir(outputPath)
if outputDir == "" {
outputDir = "."
}
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-*")View on GitHub (pinned to cd8cf15dc3)