github/copilot-sdk · error
existing binary hash mismatch
Error message
existing binary hash mismatch
What it means
installAt in go/internal/embeddedcli/embeddedcli.go hashes the CLI binary already present at the target path and compares it to config.CliHash. If they differ, it refuses to overwrite the binary and returns this error. The library treats a foreign or different-version binary at the destination as something it must not clobber.
Solutions
- Delete or rename the existing binary at finalPath and re-run install
- Verify the file was not corrupted or replaced (re-hash it and compare against config.CliHash)
- Rebuild/embed the matching CLI so config.CliHash matches the on-disk binary
- If overwrite is intended, add logic to remove the stale binary before calling install
Example fix
// before
path, err := embeddedcli.Install(ctx, cfg) // fails: existing binary hash mismatch
// after
if _, err := os.Stat(targetPath); err == nil {
os.Remove(targetPath) // remove stale/mismatched binary
}
path, err := embeddedcli.Install(ctx, cfg) Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := os.Stat(targetPath); err == nil {
sum, _ := hashFile(targetPath)
if !bytes.Equal(sum, cfg.CliHash) {
os.Remove(targetPath) // or surface a friendly message
}
} Type guard
func binaryMatches(path string, want []byte) bool {
got, err := hashFile(path)
return err == nil && bytes.Equal(got, want)
} Try / catch
path, err := embeddedcli.Install(ctx, cfg)
if err != nil {
if strings.Contains(err.Error(), "existing binary hash mismatch") {
os.Remove(targetPath)
path, err = embeddedcli.Install(ctx, cfg)
}
if err != nil { return err }
} Prevention
- Remove stale binaries before version upgrades
- Record installed version/hash in a manifest and compare before install
- Never hand-edit or replace files inside the managed install directory
When it happens
Trigger: Calling install (or installAt) when finalPath already exists and its SHA-256 hash does not equal config.CliHash — e.g. a stale build, a hand-placed binary, or an embedded config whose CliHash was regenerated after the on-disk binary was written.
Common situations: Upgrading the embedded CLI version without removing an older installed copy; another tool or user replaced the binary; a partially-patched binary; re-running install after modifying the embedded CLI bytes.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Checksum mismatch for
- checksum mismatch for
- creating binary file
- existing hash mismatch
- runtime assets hash mismatch
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/ffa595803daa64f8.
Report an issue: GitHub.
Appendix: source
Thrown at go/internal/embeddedcli/embeddedcli.go:265
// Best effort to prevent concurrent installs.
if release, _ := flock.Acquire(filepath.Join(installDir, ".copilot-cli.lock")); release != nil {
defer release()
}
binaryName := "copilot"
if runtime.GOOS == "windows" {
binaryName += ".exe"
}
finalPath := filepath.Join(installDir, binaryName)
if _, err := os.Stat(finalPath); err == nil {
existingHash, err := hashFile(finalPath)
if err != nil {
return "", fmt.Errorf("hashing existing binary: %w", err)
}
if !bytes.Equal(existingHash, config.CliHash) {
return "", fmt.Errorf("existing binary hash mismatch")
}
if config.RuntimeExecutable != nil {
path, err := installRuntimePair(installDir)
if err != nil {
return "", err
}
runtimePath = path
}
if config.RuntimeLib != nil {
libPath, err := installRuntimeLib(installDir)
if err != nil {
return "", err
}
runtimeLibPath = libPath
}
if err := installRuntimeAssets(installDir); err != nil {
return "", err
}View on GitHub (pinned to cd8cf15dc3)