multica-ai/multica · error
chmod temp file: %w
Error message
chmod temp file: %w
What it means
The temp file is chmod-ed to the original binary's mode so the replaced executable stays executable; failure is wrapped as 'chmod temp file: %w' and the temp file removed. Because CreateTemp makes 0600 files, skipping this step would break the rename, so the update aborts instead.
Source
Thrown at server/internal/cli/update.go:468
}
tmpPath := tmpFile.Name()
if _, err := tmpFile.Write(binaryData); err != nil {
tmpFile.Close()
os.Remove(tmpPath)
return "", fmt.Errorf("write temp file: %w", err)
}
tmpFile.Close()
// Preserve original file permissions.
info, err := os.Stat(exePath)
if err != nil {
os.Remove(tmpPath)
return "", fmt.Errorf("stat original binary: %w", err)
}
if err := os.Chmod(tmpPath, info.Mode()); err != nil {
os.Remove(tmpPath)
return "", fmt.Errorf("chmod temp file: %w", err)
}
// Replace the original binary. On Windows this moves the running executable
// aside first; on Unix a plain rename over the running inode is fine.
if err := replaceBinary(tmpPath, exePath); err != nil {
os.Remove(tmpPath)
return "", fmt.Errorf("replace binary: %w", err)
}
return fmt.Sprintf("Downloaded %s and replaced %s", assetName, exePath), nil
}
// extractBinaryFromTarGz reads a .tar.gz stream and returns the contents of the
// named file entry.
func extractBinaryFromTarGz(r io.Reader, name string) ([]byte, error) {
gz, err := gzip.NewReader(r)
if err != nil {
return nil, fmt.Errorf("gzip reader: %w", err)View on GitHub (pinned to 2c0912b6ec)
Solutions
- Move the binary to a POSIX-capable local filesystem (ext4, APFS, NTFS with Go-supported ACLs).
- Adjust SELinux/AppArmor policy or the directory ACLs to allow chmod by the running user.
- Ensure the process owns the files it creates in the install directory.
- Check the wrapped error path — it names the temp file that failed.
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
if info, err := os.Stat(exePath); err == nil {
if info.Mode().Perm()&0111 == 0 {
// original not executable; chmod before update to keep replace sane
}
} Try / catch
out, err := cli.UpdateViaDownload(ver)
if err != nil && strings.HasPrefix(err.Error(), "chmod temp file") {
// filesystem or MAC policy denies chmod: relocate binary to a POSIX fs
} Prevention
- Keep the binary on a POSIX-capable local filesystem
- Whitelist the install directory in SELinux/AppArmor policies
- Avoid exFAT/FAT install locations for executables
When it happens
Trigger: Filesystems that do not support chmod (some FAT/exFAT mounts, certain network filesystems, Windows ACL edge cases); the user losing ownership of the temp file mid-update; SELinux/AppArmor denying chmod on the path.
Common situations: Running the binary off an exFAT USB drive or a permissive NFS mount; hardened Linux with MAC policies on the install directory; Windows directories with restrictive inherited ACLs.
Related errors
- mint PAT: response missing token
- daemon profile is not resolved yet; token sync skipped
- runtime local skill discovery timed out
- runtime local skill import failed
- read file: %w
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/a14da7017bf0b427.
Report an issue: GitHub.