vxcontrol/pentagi · error
'%s' is not a regular file
Error message
'%s' is not a regular file
What it means
RegularFileInfo lstats the path and requires a regular file. If the Lstat succeeds but the entry is a directory, symlink, socket, FIFO, or device, it returns "'<path>' is not a regular file". UploadFlowFiles uses this to reject non-file uploads before streaming.
Source
Thrown at backend/pkg/flowfiles/files.go:311
func LocalEntryExists(filePath string) (bool, error) {
if _, err := os.Lstat(filePath); err != nil {
if errors.Is(err, os.ErrNotExist) {
return false, nil
}
return false, err
}
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()View on GitHub (pinned to ea665308ba)
Solutions
- Ensure the path refers to a regular file, not a directory or symlink, before calling.
- If uploading a directory, enumerate its files and call the upload API per regular file.
- Resolve symlinks first with filepath.EvalSymlinks or os.Stat if following links is intended, then check Mode().IsRegular() yourself.
Example fix
// before
info, err := flowfiles.RegularFileInfo("/data/mydir")
// after
entries, _ := os.ReadDir("/data/mydir")
for _, e := range entries {
if e.Type().IsRegular() {
info, err := flowfiles.RegularFileInfo(filepath.Join("/data/mydir", e.Name()))
// handle info/err
}
} Defensive patterns
Strategy: validation
Validate before calling
func ensureRegularFile(p string) error {
info, err := os.Stat(p) // Stat follows symlinks
if err != nil {
return err
}
if !info.Mode().IsRegular() {
return fmt.Errorf("%s is not a regular file", p)
}
return nil
} Type guard
func isRegularFile(p string) bool {
info, err := os.Stat(p)
return err == nil && info.Mode().IsRegular()
} Try / catch
if err != nil {
if strings.HasSuffix(err.Error(), "is not a regular file") {
return fmt.Errorf("skip or expand directories/symlinks before upload: %w", err)
}
return err
} Prevention
- Reject directory picks in the upload UI before submitting.
- Resolve or reject symlinks per your policy before upload.
- Re-check the path right before upload to avoid TOCTOU swaps.
When it happens
Trigger: Calling flowfiles.RegularFileInfo on a directory path, a symlink (Lstat does not follow links), or a special file (device/socket/FIFO) — e.g. when a user selects a folder for upload, or a path that turned out to be a symlink to a file.
Common situations: Uploading a directory instead of files from the UI/CLI; dragging a symlink into an upload form; referencing /dev/null or a Unix socket; a path that existed as a file but was replaced by a symlink between listing and upload (TOCTOU).
Related errors
- failed to resolve relative cache path: %w
- failed to open uploaded file: %w
- failed to create resources directory: %w
- bearer scheme must be used
- token can't be empty
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/c1741bbc606fa900.
Report an issue: GitHub.