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

  1. Move the cc-connect installation to a filesystem with POSIX permission support (ext4/xfs/APFS), not FAT/exFAT.
  2. Check SELinux/AppArmor denials (ausearch -m avc) and add allow rules or set permissive mode while updating.
  3. Remove immutable attributes: sudo chattr -i <path> if set.
  4. 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.
  5. 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

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


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/4595a3b3520b3d69. Report an issue: GitHub.