vxcontrol/pentagi · error

failed to set temp file permissions: %w

Error message

failed to set temp file permissions: %w

What it means

After copying, SaveToTemp calls tmp.Chmod(0644) to normalize the temp file's permissions; this error wraps a Chmod failure. The temp file is removed before returning, so no partial artifact is left behind.

Source

Thrown at backend/pkg/resources/resources.go:294

	}

	tmp, err := os.CreateTemp(dir, ".resource-upload-*")
	if err != nil {
		return "", "", 0, fmt.Errorf("failed to create temp file: %w", err)
	}
	tmpPath = tmp.Name()
	defer tmp.Close()

	h := md5.New()
	mw := io.MultiWriter(tmp, h)
	written, copyErr := io.Copy(mw, r)
	if copyErr != nil {
		os.Remove(tmpPath)
		return "", "", 0, fmt.Errorf("failed to write temp file: %w", copyErr)
	}
	if err := tmp.Chmod(0644); err != nil {
		os.Remove(tmpPath)
		return "", "", 0, fmt.Errorf("failed to set temp file permissions: %w", err)
	}

	return tmpPath, hex.EncodeToString(h.Sum(nil)), written, nil
}

// CommitBlob atomically moves tmpPath to the .blob destination for hash.  If
// the blob already exists (race with concurrent upload of identical file) the
// tmp file is removed and no error is returned.
func CommitBlob(dataDir, hash, tmpPath string) error {
	if err := validateBlobHash(hash); err != nil {
		return err
	}
	if err := EnsureResourcesDir(dataDir); err != nil {
		return err
	}

	dest := BlobPath(dataDir, hash)
	if _, err := os.Lstat(dest); err == nil {

View on GitHub (pinned to ea665308ba)

Solutions

  1. Move the resources/temp directory to a POSIX-permission-capable filesystem (ext4/xfs local volume)
  2. If the mount can't support chmod, patch the workflow to tolerate the failure or use a different storage backend
  3. Check mount options (mount output) and remount without permission-squashing flags
  4. Verify nothing concurrently deletes files from dir during upload

Example fix

// before
# docker-compose.yml
- ./resources:/var/lib/pentagi/resources  # on CIFS/SMB share
// after
- pentagi_resources:/var/lib/pentagi/resources  # native docker volume (ext4)
Defensive patterns

Strategy: try-catch

Validate before calling

func supportsChmod(dir string) error {
	f, err := os.CreateTemp(dir, ".chmod-probe-*")
	if err != nil {
		return err
	}
	defer os.Remove(f.Name())
	return f.Chmod(0644)
}

Try / catch

tmpPath, hash, size, err := resources.SaveToTemp(r, dir)
if err != nil {
	if strings.Contains(err.Error(), "failed to set temp file permissions") {
		log.Warn("filesystem does not support chmod; use a POSIX volume", "dir", dir)
		return http.StatusInternalServerError
	}
	return err
}

Prevention

When it happens

Trigger: Chmod fails because the filesystem doesn't support permission changes (some NFS exports, FAT/exFAT mounts, certain FUSE filesystems), or the file was concurrently removed.

Common situations: Storing resources on an NFS share with all_squash or on a Windows/SMB mount; Docker volumes backed by a filesystem ignoring chmod; tmpfs quirks in restricted container runtimes.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/840fb1e1156277d7. Report an issue: GitHub.