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
- Move PluginsDir to a local filesystem that supports fsync and retry
- If on network storage, adjust mount options (e.g. CIFS 'sync' semantics) per your platform docs
- 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
- Do not host the plugins directory on FUSE/sshfs-style mounts
- For network mounts, configure them with fsync semantics your platform supports
- Take repeated sync EIO errors seriously — they often precede hardware failure
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
- close temp plugin file: %w
- failed to read auth file: %w
- failed to write token to file: %w
- failed to read auth file: %w
- failed to write auth file: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/c6b7a126cc034b11.
Report an issue: GitHub.