github/copilot-sdk · error
creating install directory
Error message
creating install directory: %w
What it means
installAt creates the versioned install directory (with MkdirAll) before laying down the CLI binary and assets. If directory creation fails, the error is wrapped with this message. It prevents installation from proceeding without a writable target directory.
Solutions
- Check the wrapped err for the exact cause (EACCES, ENOTDIR, EROFS)
- Create the parent install dir with proper ownership/permissions (sudo mkdir + chown) or point the install dir at a user-writable location (e.g. under $HOME)
- If a file exists where the directory should be, remove or rename it
- Avoid read-only filesystems, or install to a writable volume
Example fix
// before
// installAt("/usr/local/lib/copilot", ...) fails with permission denied
// after
dir := os.Getenv("XDG_DATA_HOME")
if dir == "" { dir = filepath.Join(os.Getenv("HOME"), ".local", "share") }
path, err := installAt(filepath.Join(dir, "copilot"), version) Defensive patterns
Strategy: try-catch
Validate before calling
// verify the install root is writable before installing
if err := os.MkdirAll(installRoot, 0755); err != nil { /* pick a writable dir */ } Try / catch
// Go
path, err := installAt(dir, version)
var pe *fs.PathError
if err != nil && errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {
// fall back to a user-writable install location
} Prevention
- Default installs under $HOME or XDG dirs instead of system paths
- Check writability of the install root at startup
- Never let a regular file occupy the install directory path
When it happens
Trigger: os.MkdirAll on the install path fails: parent dir not writable, path exists as a regular file, read-only filesystem, or SELinux/AppArmor denial.
Common situations: Installing into a system path like /usr/local/lib without sudo; install root pre-empted by a stale file with the same name; running in a read-only container filesystem; multi-user machines where another user owns the version directory.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- not found at .
- Published runtime wrapper is not a non-empty executable…
- Failed to make Copilot CLI executable:
- failed to chmod binary
- hashing existing binary
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/0573727e38ced4ba.
Report an issue: GitHub.
Appendix: source
Thrown at go/internal/embeddedcli/embeddedcli.go:245
cfg.RuntimeAssetsHash = cfg.LinuxMuslRuntimeAssetsHash
return cfg
}
func isMusl() bool {
out, _ := exec.Command("ldd", "--version").CombinedOutput()
return strings.Contains(strings.ToLower(string(out)), "musl")
}
func installAt(installDir string) (string, error) {
version := sanitizeVersion(config.Version)
if version != "" {
installDir = filepath.Join(installDir, version)
}
if linuxMuslBundle {
installDir = filepath.Join(installDir, "linuxmusl")
}
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)
}View on GitHub (pinned to cd8cf15dc3)