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 nil

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Check free space and dmesg/agent logs for I/O errors on the plugins volume
  2. Retry the install once transient storage pressure clears (installArchive is idempotent — byte-identical libraries are skipped at install.go:279-287)
  3. 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

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


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