router-for-me/CLIProxyAPI · error
close temp plugin file: %w
Error message
close temp plugin file: %w
What it means
Wrapped error from temp.Close in writeFileAtomic (install.go:554-556). After chmod/write/sync succeed, the staged file is closed before the rename. Close errors are uncommon but surface deferred write-back failures on some filesystems; if it fails, the install aborts and the temp file is removed by the deferred cleanup (closed stays false).
Source
Thrown at internal/pluginstore/install.go:555
}
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)
}
removeTemp = false
return nilView on GitHub (pinned to 78f0c4079e)
Solutions
- Check free space and dmesg/agent logs for I/O errors on the plugins volume
- Retry the install once transient storage pressure clears (installArchive is idempotent — byte-identical libraries are skipped at install.go:279-287)
- Move PluginsDir off the misbehaving mount
Defensive patterns
Strategy: retry
Try / catch
if _, err := store.InstallArchive(data, plugin, opts); err != nil {
if strings.Contains(err.Error(), "close temp plugin file") {
// transient flush failure: verify free space, then retry install once
}
} Prevention
- Keep headroom on the plugins volume so buffered writes can flush at close
- Retry installs after storage pressure clears — identical bytes are skipped on retry
- Watch kernel logs for I/O errors on the plugins device
When it happens
Trigger: InstallArchive where closing the flushed temp file fails with EIO/ENOSPC on write-back (data buffered in the page cache may fail to flush at close), or on unusual FUSE filesystems.
Common situations: Disk that filled between write and close due to concurrent writes by other processes; flaky network-mounted storage.
Related errors
- sync 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/5ae3a9fe8a6336d4.
Report an issue: GitHub.