chenhg5/cc-connect · error

install new binary: %w

Error message

install new binary: %w

What it means

replaceExecutable copies the freshly built binary over the running install path during `cc-connect update`. When copyFile fails (e.g. disk full, target busy, permission issue), it tries to restore the backup of the old binary and wraps the copy error as "install new binary: %w". This means the update's install step failed, though the tool attempted to roll back to the previous binary.

Source

Thrown at cmd/cc-connect/update.go:447

	if err := os.Chmod(src, 0o755); err != nil {
		return fmt.Errorf("chmod: %w", err)
	}

	// On Windows, rename over a running exe is not possible directly.
	// Move old binary aside, then move new one in.
	backup := target + ".old"
	os.Remove(backup)

	if err := os.Rename(target, backup); err != nil {
		return fmt.Errorf("backup old binary: %w", err)
	}

	if err := copyFile(src, target); err != nil {
		// Attempt to restore
		if restoreErr := os.Rename(backup, target); restoreErr != nil {
			slog.Warn("update: failed to restore old binary after copy error", "error", restoreErr)
		}
		return fmt.Errorf("install new binary: %w", err)
	}

	if err := os.Chmod(target, 0o755); err != nil {
		return fmt.Errorf("chmod new binary: %w", err)
	}

	os.Remove(backup)
	return nil
}

func copyFile(src, dst string) error {
	in, err := os.Open(src)
	if err != nil {
		return err
	}
	defer in.Close()

	out, err := os.Create(dst)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check free disk space (df -h) on the filesystem containing the binary and free space if full.
  2. Verify write permissions on the target path (ls -l $(which cc-connect)) and re-run with sufficient privileges.
  3. Check the wrapped root cause in the error message (%w) and logs: 'update: failed to restore old binary after copy error' would indicate the rollback also failed.
  4. As a fallback, manually download/build the new binary and replace it, then restart the daemon.
  5. If the target is locked by a running process, stop the cc-connect daemon/service before updating.

Example fix

// before (run as unprivileged user, target owned by root)
cc-connect update
// install new binary: chmod /usr/local/bin/cc-connect: permission denied

// after
sudo chown $(whoami) /usr/local/bin/cc-connect
cc-connect update
Defensive patterns

Strategy: try-catch

Validate before calling

if st, err := os.Stat(target); err == nil {
    if f, err := os.OpenFile(target, os.O_WRONLY, st.Mode()); err != nil {
        return fmt.Errorf("target not writable: %w", err)
    } else { f.Close() }
}

Try / catch

if err := runUpdate(); err != nil {
    if strings.Contains(err.Error(), "install new binary") {
        slog.Warn("update failed at install step; old binary may have been restored", "err", err)
        // verify binary still runs before retrying
    }
}

Prevention

When it happens

Trigger: Running `cc-connect update`; replaceExecutable is called from runUpdate after a successful build, and os.CopyFile/copyFile(src, target) fails — typically write errors on the target path, out-of-disk, or the target being locked.

Common situations: Disk quota exceeded on the volume holding the binary; target directory owned by root while running as non-root; antivirus/file-lock on Windows-style mounts; read-only filesystem after a failed mount; interrupted download leaving a corrupt build in src.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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