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
- Delete stale wrapper artifacts and rerun the bundler.
- Check permissions on wrapperArtifactPath.
- Serialize builds so only one bundler run owns the output directory.
- Exclude the output dir from concurrent clean/AV jobs.
- 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
- Serialize bundler runs with a lock file on the output directory.
- Exclude the output dir from concurrent cleanup jobs.
- Restore from CI cache only complete artifact sets.
- Check permissions after any tooling changes.
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
- failed to hash existing output
- failed to hash existing runtime.node
- 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/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)