vxcontrol/pentagi · error
failed to create file '%s': %w
Error message
failed to create file '%s': %w
What it means
ExtractTar opens each regular-file entry with os.OpenFile(entryPath, O_CREATE|O_WRONLY|O_TRUNC, 0644) after its parent directory exists; failure here aborts with this error. Because the path was already sanitized and parents created, causes are filesystem-level: permissions, read-only volume, name conflicts, or resource exhaustion (too many open files).
Source
Thrown at backend/pkg/flowfiles/files.go:420
if hdr.Size < 0 {
return fmt.Errorf("tar entry '%s' has invalid size %d", hdr.Name, hdr.Size)
}
filesCount++
if filesCount > MaxPullFiles {
return fmt.Errorf("tar archive exceeds maximum file count of %d", MaxPullFiles)
}
totalSize += hdr.Size
if totalSize > MaxPullTotalSize {
return fmt.Errorf("tar archive exceeds maximum total size of %d bytes", MaxPullTotalSize)
}
if err := os.MkdirAll(filepath.Dir(entryPath), 0755); err != nil {
return fmt.Errorf("failed to create parent directory for '%s': %w", entryPath, err)
}
f, err := os.OpenFile(entryPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
return fmt.Errorf("failed to create file '%s': %w", entryPath, err)
}
_, copyErr := io.CopyN(f, tr, hdr.Size)
f.Close()
if copyErr != nil {
return fmt.Errorf("failed to write file '%s': %w", entryPath, copyErr)
}
}
}
return nil
}
func ZipDirectory(w io.Writer, dirPath string) (err error) {
zw := zip.NewWriter(w)
defer func() {
if cerr := zw.Close(); err == nil {
err = cerr
}View on GitHub (pinned to ea665308ba)
Solutions
- Read the wrapped errno: EACCES/EROFS → fix volume permissions or mount rw; EISDIR → clear the conflicting directory from a prior extraction; EMFILE → raise ulimit -n or fix fd leaks.
- Sanitize/flatten entry names when producing the tar to avoid characters invalid on the target OS.
- Ensure the process user owns destDir (chown -R service:service destDir).
- Check disk space (ENOSPC) on the destination volume.
Example fix
// before
err := flowfiles.ExtractTar(rc, destDir)
// after
// run as the volume owner or pre-chown the dir:
// $ chown -R 10001:10001 /var/lib/pentagi/uploads
if err := os.MkdirAll(destDir, 0o755); err != nil { return err }
err := flowfiles.ExtractTar(rc, destDir) Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure destDir is writable and the process is under fd limits:
info, err := os.Stat(destDir)
if err != nil || !info.IsDir() {
return fmt.Errorf("destDir missing or not a directory")
}
if err := unix.Access(destDir, unix.W_OK); err != nil {
return fmt.Errorf("destDir not writable by current user: %w", err)
} Try / catch
err := flowfiles.ExtractTar(rc, destDir)
if err != nil {
var pe *fs.PathError
if errors.As(err, &pe) {
switch {
case errors.Is(pe.Err, syscall.EACCES), errors.Is(pe.Err, syscall.EROFS):
return fmt.Errorf("cannot write into %s (check ownership/mount): %w", destDir, err)
case errors.Is(pe.Err, syscall.EMFILE), errors.Is(pe.Err, syscall.ENFILE):
return fmt.Errorf("fd limit exhausted: %w", err)
case errors.Is(pe.Err, syscall.EISDIR):
return fmt.Errorf("stale directory blocks a file entry; clean destDir: %w", err)
case errors.Is(pe.Err, syscall.ENOSPC):
return fmt.Errorf("disk full: %w", err)
}
}
return err
} Prevention
- Run the service as the owner of the destination volume, or chown the uploads dir at startup.
- Mount destination volumes read-write; avoid read-only rootfs for extraction targets.
- Watch open-file-descriptor usage (lsof | wc -l vs ulimit -n) on busy instances.
- Sanitize archive entry names at production time to characters valid on the target OS.
- Extract to a fresh temp dir per request and swap into place atomically.
When it happens
Trigger: os.OpenFile fails during PullFlowFiles extraction: destDir volume is read-only or lacks write permission, a directory already exists at entryPath (EISDIR), filename contains characters invalid for the host FS, EMFILE/ENFILE fd exhaustion, or disk full at open/truncate time.
Common situations: Archives built on case-sensitive/other-OS filesystems with characters like ':' or '\\' extracted onto stricter filesystems; service running as unprivileged UID against a root-owned volume; fd leaks elsewhere in the process hitting the ulimit.
Related errors
- failed to create directory '%s': %w
- failed to create parent directory for '%s': %w
- failed to create tmp directory: %w
- failed to set temporary upload file permissions: %w
- failed to delete blob %s: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/7d5ce4e077e3f8c3.
Report an issue: GitHub.