github/copilot-sdk · error
hashing existing binary
Error message
hashing existing binary: %w
What it means
If a binary already exists at the target install path, installAt hashes it with hashFile to decide whether it matches the expected content. When hashing itself fails (e.g. permission denied reading the file, or the path is a directory), the error is wrapped with this message. This is distinct from the hash mismatch error that follows a successful hash.
Solutions
- Check the wrapped error for the exact cause and fix file permissions (chmod/chown) so the file is readable
- If the path is a broken symlink or directory, remove it and reinstall
- Take the install lock or stop concurrent installers, then retry the install
- As a last resort delete the versioned install dir and perform a clean install
Example fix
// before // failure: hashing existing binary: open .../copilot: permission denied // after $ sudo chmod a+r /path/to/install/<version>/copilot # make existing binary readable $ # or remove and reinstall: $ rm -f /path/to/install/<version>/copilot && retry install
Defensive patterns
Strategy: retry
Validate before calling
// ensure the existing binary is readable before install
if fi, err := os.Stat(finalPath); err == nil {
f, err := os.Open(finalPath); if err != nil { /* fix perms or remove */ } else { f.Close() }
} Try / catch
// Go
path, err := installAt(dir, version)
if err != nil && strings.Contains(err.Error(), "hashing existing binary") {
// remove the unreadable/stale file and retry once
os.Remove(filepath.Join(dir, binaryName))
path, err = installAt(dir, version)
} Prevention
- Run installs under one user with consistent file modes
- Serialize installs with the provided flock to avoid races
- Verify symlinks in install dirs resolve to regular files
When it happens
Trigger: os.Stat reports the binary exists, but hashFile (which opens and reads the file) fails — unreadable permissions, file replaced by a directory/symlink to nowhere mid-check, or I/O error while reading.
Common situations: Another user's install left the binary mode 0600; a broken or malicious symlink at binaryName; antivirus or disk errors preventing reads; concurrent installs racing on the same path (the flock is best-effort and may not have been acquired).
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
- not found at .
- creating install directory
- hashing existing
- at is empty.
- Could not resolve . Reinstall @github/copilot-sdk so its…
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/768f381b8c20adeb.
Report an issue: GitHub.
Appendix: source
Thrown at go/internal/embeddedcli/embeddedcli.go:262
if err := os.MkdirAll(installDir, 0755); err != nil {
return "", fmt.Errorf("creating install directory: %w", err)
}
// 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
}View on GitHub (pinned to cd8cf15dc3)