router-for-me/CLIProxyAPI · error

sync temp plugin file: %w

Error message

sync temp plugin file: %w

What it means

Wrapped error from temp.Sync in writeFileAtomic (install.go:551-553). The staged temp file is fsync'ed before rename so the library is durable on disk before it becomes visible. Sync failing usually means storage-level trouble — EIO, or sync unsupported/disallowed by the mount.

Source

Thrown at internal/pluginstore/install.go:552

			if errClose := temp.Close(); errClose != nil {
				log.WithError(errClose).Debug("failed to close temp plugin file")
			}
		}
		if removeTemp {
			if errRemove := os.Remove(tempPath); errRemove != nil && !errors.Is(errRemove, os.ErrNotExist) {
				log.WithError(errRemove).Debug("failed to remove temp plugin file")
			}
		}
	}()

	if errChmod := temp.Chmod(mode); errChmod != nil {
		return fmt.Errorf("chmod temp plugin file: %w", errChmod)
	}
	if _, errWrite := temp.Write(data); errWrite != nil {
		return fmt.Errorf("write temp plugin file: %w", errWrite)
	}
	if errSync := temp.Sync(); errSync != nil {
		return fmt.Errorf("sync temp plugin file: %w", errSync)
	}
	if errClose := temp.Close(); errClose != nil {
		return fmt.Errorf("close temp plugin file: %w", errClose)
	}
	closed = true
	if errRename := os.Rename(tempPath, targetPath); errRename != nil {
		if runtime.GOOS == "windows" {
			if errRemove := os.Remove(targetPath); errRemove != nil && !errors.Is(errRemove, os.ErrNotExist) {
				return fmt.Errorf("remove old plugin file: %w", errRemove)
			}
			if errRenameRetry := os.Rename(tempPath, targetPath); errRenameRetry == nil {
				removeTemp = false
				return nil
			} else {
				return fmt.Errorf("install plugin file: %w", errRenameRetry)
			}
		}
		return fmt.Errorf("install plugin file: %w", errRename)

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Move PluginsDir to a local filesystem that supports fsync and retry
  2. If on network storage, adjust mount options (e.g. CIFS 'sync' semantics) per your platform docs
  3. Investigate repeated EIO — it frequently precedes disk failure
Defensive patterns

Strategy: fallback

Validate before calling

func fsyncSupported(dir string) error {
    p := filepath.Join(dir, ".sync-probe")
    f, err := os.Create(p)
    if err != nil { return err }
    defer os.Remove(p)
    defer f.Close()
    return f.Sync()
}

Try / catch

if _, err := store.InstallArchive(data, plugin, opts); err != nil {
    if strings.Contains(err.Error(), "sync temp plugin file") {
        // mount-level fsync failure: relocate PluginsDir to local disk and retry
    }
}

Prevention

When it happens

Trigger: InstallArchive with PluginsDir on a filesystem where fsync returns an error (some network mounts, vfat under certain conditions, FUSE filesystems with sync disabled, or real device errors).

Common situations: Plugins dir on a FUSE/network mount (sshfs, some CIFS configs) that rejects fsync; failing hardware; VMs with misconfigured virtio storage.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/c6b7a126cc034b11. Report an issue: GitHub.