github/copilot-sdk · error
checking existing permissions
Error message
checking existing %s permissions: %w
What it means
When an existing file matches the expected hash, installVerifiedFile still ensures it is executable on non-Windows platforms. This error wraps an os.Stat failure that occurs while re-checking the existing file's permissions after the hash check succeeded.
Solutions
- Serialize installs — don't run two installs into the same installDir concurrently.
- Re-run the install; the file will be rewritten since it no longer exists.
- Check what external process (e.g. a cleaner/AV) removes files from the install directory.
Defensive patterns
Strategy: retry
Try / catch
err := client.InstallAt(dir)
if err != nil && strings.Contains(err.Error(), "checking existing") {
time.Sleep(100 * time.Millisecond)
err = client.InstallAt(dir) // transient race: file vanished mid-install
} Prevention
- Serialize installs to the same directory with a lock
- Avoid running concurrent app instances during first-run install
When it happens
Trigger: os.Stat(path) fails in the permission-restoration branch — the file was removed or became inaccessible between the initial Stat/hashFile and this second Stat.
Common situations: A concurrent process deleting or replacing the installed binary mid-install; a race between two simultaneous installs into the same directory.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Concurrent extraction race: target already exists but is…
- Published runtime wrapper is not a non-empty executable…
- Failed to make Copilot CLI executable:
- failed to chmod binary
- creating install directory
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/5ce47b35e78d91f6.
Report an issue: GitHub.
Appendix: source
Thrown at go/internal/embeddedcli/embeddedcli.go:456
if err := installVerifiedFile(wrapperPath, config.RuntimeExecutable, config.RuntimeExecutableHash, 0755, "runtime wrapper"); err != nil {
return "", err
}
return wrapperPath, nil
}
func installVerifiedFile(path string, reader io.Reader, expectedHash []byte, mode os.FileMode, label string) error {
if _, err := os.Stat(path); err == nil {
existingHash, err := hashFile(path)
if err != nil {
return fmt.Errorf("hashing existing %s: %w", label, err)
}
if !bytes.Equal(existingHash, expectedHash) {
return fmt.Errorf("existing %s hash mismatch", label)
}
if runtime.GOOS != "windows" && mode.Perm()&0111 != 0 {
info, err := os.Stat(path)
if err != nil {
return fmt.Errorf("checking existing %s permissions: %w", label, err)
}
if info.Mode().Perm()&0111 == 0 {
if err := os.Chmod(path, info.Mode().Perm()|mode.Perm()&0111); err != nil {
return fmt.Errorf("restoring existing %s permissions: %w", label, err)
}
}
}
return nil
}
tmp, err := os.CreateTemp(filepath.Dir(path), ".copilot-runtime-pair-*.tmp")
if err != nil {
return fmt.Errorf("creating temporary %s: %w", label, err)
}
tmpPath := tmp.Name()
h := sha256.New()
_, err = io.Copy(io.MultiWriter(tmp, h), reader)
if err1 := tmp.Chmod(mode); err1 != nil && err == nil {View on GitHub (pinned to cd8cf15dc3)