vxcontrol/pentagi · error
failed to write temporary upload file: %w
Error message
failed to write temporary upload file: %w
What it means
After creating the temp file, SaveUploadedFileToTemp copies the multipart source into it with io.Copy. If the copy fails mid-stream, the partially written temp file is removed (os.Remove) and this error is returned with the underlying cause (client disconnect, disk full, read error on the multipart stream).
Source
Thrown at backend/pkg/flowfiles/files.go:333
}
func SaveUploadedFileToTemp(fh *multipart.FileHeader, dir string) (string, error) {
src, err := fh.Open()
if err != nil {
return "", fmt.Errorf("failed to open uploaded file: %w", err)
}
defer src.Close()
dst, err := os.CreateTemp(dir, ".upload-*")
if err != nil {
return "", fmt.Errorf("failed to create temporary upload file: %w", err)
}
tmpPath := dst.Name()
defer dst.Close()
if _, err := io.Copy(dst, src); err != nil {
os.Remove(tmpPath)
return "", fmt.Errorf("failed to write temporary upload file: %w", err)
}
if err := dst.Chmod(0644); err != nil {
os.Remove(tmpPath)
return "", fmt.Errorf("failed to set temporary upload file permissions: %w", err)
}
return tmpPath, nil
}
func IsWithinDir(absPath, dir string) bool {
return strings.HasPrefix(
filepath.Clean(absPath)+string(filepath.Separator),
filepath.Clean(dir)+string(filepath.Separator),
)
}
func ResolvePulledStagedTarget(stagingDir, cacheRelPath string) string {
candidates := []string{View on GitHub (pinned to ea665308ba)
Solutions
- Check whether the wrapped error is syscall.EPIPE / 'unexpected EOF' — the client disconnected; treat as benign client-abort and log at info level.
- Free disk space or raise the volume quota for the temp/upload directory.
- Increase reverse-proxy (nginx client_body_timeout / proxy_read_timeout) and body size limits for large uploads.
- Retry the upload client-side on transient network errors; the temp file is cleaned up automatically.
Example fix
// before
tmpPath, err := flowfiles.SaveUploadedFileToTemp(fh, dir)
if err != nil {
return err
}
// after
tmpPath, err := flowfiles.SaveUploadedFileToTemp(fh, dir)
if err != nil {
if errors.Is(err, syscall.EPIPE) || errors.Is(err, io.ErrUnexpectedEOF) {
log.Info().Err(err).Msg("client aborted upload")
return nil
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check rough size before streaming if the request declares Content-Length:
if r.ContentLength > maxAllowedUpload {
http.Error(w, "file too large", http.StatusRequestEntityTooLarge)
return
} Try / catch
tmpPath, err := flowfiles.SaveUploadedFileToTemp(fh, dir)
if err != nil {
if errors.Is(err, syscall.EPIPE) || errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, context.Canceled) {
log.Info().Err(err).Msg("upload aborted by client") // temp file already cleaned up
return
}
if errors.Is(err, syscall.ENOSPC) {
http.Error(w, "storage full", http.StatusInsufficientStorage)
return
}
http.Error(w, "upload failed", http.StatusInternalServerError)
return
} Prevention
- Enforce max upload size at the proxy and in handler before reading the body.
- Keep generous disk headroom on the temp/upload volume; monitor with alerts.
- Tune nginx/proxy read timeouts to exceed expected upload durations.
- Remember the function removes the partial temp file — never reuse tmpPath after an error.
When it happens
Trigger: io.Copy(dst, src) returns an error during UploadFlowFiles: the HTTP client disconnected mid-upload (broken pipe / context cancel), the disk filled while writing, or reading from the multipart.FileHeader failed.
Common situations: Users canceling large uploads; reverse proxies (nginx) timing out and dropping the connection; small container disk quotas exceeded by a big file; network interruption between proxy and backend.
Related errors
- failed to create temporary upload file: %w
- failed to write temp file: %w
- failed to create temp directory: %w
- failed to create temp file: %w
- ErrResourcesInvalidRequest
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/7bb7196ad6837504.
Report an issue: GitHub.