vxcontrol/pentagi · error
failed to open uploaded file: %w
Error message
failed to open uploaded file: %w
What it means
SaveUploadedFileToTemp opens the multipart.FileHeader's underlying part via fh.Open(). If that fails (rare — usually a malformed multipart body or the underlying reader/pipes being broken), it returns 'failed to open uploaded file' wrapping the cause.
Source
Thrown at backend/pkg/flowfiles/files.go:320
return true, nil
}
func RegularFileInfo(filePath string) (os.FileInfo, error) {
info, err := os.Lstat(filePath)
if err != nil {
return nil, err
}
if !info.Mode().IsRegular() {
return nil, fmt.Errorf("'%s' is not a regular file", filePath)
}
return info, nil
}
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)
}View on GitHub (pinned to ea665308ba)
Solutions
- Confirm the FileHeader came from a successfully parsed request (r.ParseMultipartForm / c.FormFile), not a manually constructed struct.
- Check the wrapped cause (%w) for http.ErrMissingFile or reader errors and return 400 Bad Request to the client.
- For tests, build the FileHeader via a real multipart writer/reader round-trip instead of setting fields directly.
- Retry or reject on client disconnect — this is a client-side failure, not a server bug.
Example fix
// before
fh, _ := c.FormFile("file")
path, err := flowfiles.SaveUploadedFileToTemp(fh, dir) // panics/fails on nil or fake fh
// after
fh, err := c.FormFile("file")
if err != nil {
c.JSON(400, gin.H{"error": "file part missing"}); return
}
path, err := flowfiles.SaveUploadedFileToTemp(fh, dir)
if err != nil {
c.JSON(400, gin.H{"error": err.Error()}); return
} Defensive patterns
Strategy: try-catch
Validate before calling
if fh == nil || fh.Size == 0 && fh.Filename == "" {
return errors.New("no valid uploaded file part")
} Type guard
func hasRealUpload(fh *multipart.FileHeader) bool {
if fh == nil || fh.Filename == "" {
return false
}
f, err := fh.Open()
if err != nil {
return false
}
f.Close()
return true
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "failed to open uploaded file") {
if errors.Is(err, http.ErrMissingFile) {
return fmt.Errorf("client sent no file part: %w", err)
}
return fmt.Errorf("upload aborted or malformed: %w", err)
}
return err
} Prevention
- Obtain FileHeaders only from a successfully parsed multipart form.
- Return 400 to clients whose upload body is truncated or aborted.
- In tests, construct FileHeaders via a real multipart writer, not struct literals.
When it happens
Trigger: Calling SaveUploadedFileToTemp with a *multipart.FileHeader whose Open() fails: a truncated or malformed multipart body, an in-memory/piped FileHeader (e.g. built manually with FileHeader{Filename: ...} without setting Content or a valid open func), or the client disconnecting mid-request so the multipart reader is closed.
Common situations: Manually constructed multipart.FileHeader values in tests or code (fh.Open() returns http.ErrMissingFile or ErrMissingBoundary-adjacent failures); aborted uploads where the client closed the connection before the form finished parsing; requests where c.File or FormFile ran against a corrupted body.
Related errors
- FlowFiles.InvalidRequest
- '%s' is not a regular file
- bearer scheme must be used
- token can't be empty
- token validation disabled with default salt
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/6fa46cbff228ab10.
Report an issue: GitHub.