chenhg5/cc-connect · error
chmod: %w
Error message
chmod: %w
What it means
The temp file must be marked executable, so replaceBinary runs os.Chmod(tmpPath, 0o755); failure (after cleanup) is wrapped as "chmod: %w". Without this, the staged binary could not be executed after the swap.
Source
Thrown at core/updater.go:271
}
dir := filepath.Dir(execPath)
tmpFile, err := os.CreateTemp(dir, "cc-connect-update-*")
if err != nil {
return fmt.Errorf("create temp file: %w", err)
}
tmpPath := tmpFile.Name()
if _, err := tmpFile.Write(newBinary); err != nil {
tmpFile.Close()
os.Remove(tmpPath)
return fmt.Errorf("write new binary: %w", err)
}
tmpFile.Close()
if err := os.Chmod(tmpPath, 0o755); err != nil {
os.Remove(tmpPath)
return fmt.Errorf("chmod: %w", err)
}
oldPath := execPath + ".old"
os.Remove(oldPath)
if err := os.Rename(execPath, oldPath); err != nil {
os.Remove(tmpPath)
return fmt.Errorf("backup old binary: %w", err)
}
if err := os.Rename(tmpPath, execPath); err != nil {
// Try to restore
if restoreErr := os.Rename(oldPath, execPath); restoreErr != nil {
slog.Error("updater: failed to restore old binary after install failed", "error", restoreErr)
}
return fmt.Errorf("install new binary: %w", err)
}
View on GitHub (pinned to 4000b2338a)
Solutions
- Move the cc-connect installation to a filesystem with POSIX permission support (ext4/xfs/APFS), not FAT/exFAT.
- Check SELinux/AppArmor denials (ausearch -m avc) and add allow rules or set permissive mode while updating.
- Remove immutable attributes: sudo chattr -i <path> if set.
- Since the temp file was just created by the same process, failure here is rare — verify ownership with ls -l on the temp leftovers (none should exist; the updater cleans up) and directory mount options.
- Retry the update after fixing the mount/policy; the updater removes the temp file on failure so no stale artifacts remain.
Example fix
# before: install dir on exFAT USB mount /opt/usb/cc-connect (mount -t exfat) -> chmod: operation not permitted # after sudo mv /opt/usb/cc-connect /opt/cc-connect && /opt/cc-connect/cc-connect update
Defensive patterns
Strategy: validation
Validate before calling
var st syscall.Statfs_t
if err := syscall.Statfs(installDir, &st); err == nil {
if st.Flags&unix.ST_NOSUID != 0 || isFAT(exoticMount) {
return fmt.Errorf("filesystem %d may not support chmod", st.Flags)
}
} Try / catch
if err := selfUpdate(); err != nil {
if strings.Contains(err.Error(), "chmod") {
// move installation to a POSIX-permission filesystem and retry
}
} Prevention
- Install on ext4/xfs/APFS, not FAT/exFAT/FUSE mounts
- Check SELinux/AppArmor audit logs if chmod fails unexpectedly
- Avoid chattr +i on install directories
When it happens
Trigger: SelfUpdate -> replaceBinary: os.Chmod failed on the freshly created temp file — file owned by another user (unusual), filesystem does not support permission changes (some FUSE/mounts, FAT/exFAT drives), or ACL/immutable attributes interfere.
Common situations: Binary directory on a USB/exFAT/FAT32 mount without POSIX permissions; FUSE filesystem (e.g. some network mounts) rejecting chmod; security software or MAC policies (SELinux) denying the operation; immutable attribute inherited from the directory.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
Related errors
- create temp file: %w
- chmod task script: %w
- read existing Agy hooks %s: %w
- claudecode: create usage temp dir: %w
- claudecode: chmod per-spawn prompt file 0o644: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/4595a3b3520b3d69.
Report an issue: GitHub.