{"record":{"id":"4d5dd56711d9fa1d","repo":"vxcontrol/pentagi","slug":"failed-to-create-directory-s-w","errorCode":null,"errorMessage":"failed to create directory '%s': %w","messagePattern":"failed to create directory '(.+?)': %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/flowfiles/files.go","lineNumber":399,"sourceCode":"\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to read tar entry: %w\", err)\n\t\t}\n\t\tif hdr.Typeflag == tar.TypeSymlink || hdr.Typeflag == tar.TypeLink {\n\t\t\tcontinue\n\t\t}\n\n\t\tentryPath := filepath.Join(destDir, filepath.Clean(filepath.FromSlash(hdr.Name)))\n\t\tif !IsWithinDir(entryPath, destDir) {\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch hdr.Typeflag {\n\t\tcase tar.TypeDir:\n\t\t\tif err := os.MkdirAll(entryPath, 0755); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create directory '%s': %w\", entryPath, err)\n\t\t\t}\n\t\tcase tar.TypeReg, tar.TypeRegA:\n\t\t\tif hdr.Size < 0 {\n\t\t\t\treturn fmt.Errorf(\"tar entry '%s' has invalid size %d\", hdr.Name, hdr.Size)\n\t\t\t}\n\t\t\tfilesCount++\n\t\t\tif filesCount > MaxPullFiles {\n\t\t\t\treturn fmt.Errorf(\"tar archive exceeds maximum file count of %d\", MaxPullFiles)\n\t\t\t}\n\t\t\ttotalSize += hdr.Size\n\t\t\tif totalSize > MaxPullTotalSize {\n\t\t\t\treturn fmt.Errorf(\"tar archive exceeds maximum total size of %d bytes\", MaxPullTotalSize)\n\t\t\t}\n\n\t\t\tif err := os.MkdirAll(filepath.Dir(entryPath), 0755); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create parent directory for '%s': %w\", entryPath, err)\n\t\t\t}\n","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/flowfiles/files.go#L381-L417","documentation":"For a tar entry of type TypeDir, ExtractTar runs os.MkdirAll(entryPath, 0755) and wraps any failure in this error. The path has already been cleaned and containment-checked, so failures are environmental: the filesystem refused directory creation at the sanitized path.","triggerScenarios":"os.MkdirAll fails while extracting a directory entry from PullFlowFiles' archive: destDir does not exist or is read-only, a file already exists at entryPath (MkdirAll returns ENOTDIR), disk full, or permission denied.","commonSituations":"Re-extracting an archive over a previous extraction where a stale file occupies a directory path; read-only container volume; running the service as a non-root user lacking write access to destDir.","solutions":["Ensure destDir exists and is writable before calling ExtractTar (os.MkdirAll(destDir, 0755)).","Clean stale extraction targets: remove a conflicting non-directory file at the entry path (check the wrapped os error for ENOTDIR/EEXIST).","Fix ownership/permissions of destDir for the service account.","Check disk space on the destination volume."],"exampleFix":"// before\nif err := flowfiles.ExtractTar(rc, destDir); err != nil { return err }\n// after\nif err := os.MkdirAll(destDir, 0o755); err != nil { return err }\nif err := flowfiles.ExtractTar(rc, destDir); err != nil { return err }","handlingStrategy":"validation","validationCode":"info, err := os.Stat(destDir)\nif err != nil {\n    if err := os.MkdirAll(destDir, 0o755); err != nil {\n        return fmt.Errorf(\"cannot prepare destDir: %w\", err)\n    }\n} else if !info.IsDir() {\n    return fmt.Errorf(\"%s exists and is not a directory\", destDir)\n}","typeGuard":null,"tryCatchPattern":"err := flowfiles.ExtractTar(rc, destDir)\nif err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && (errors.Is(pe.Err, syscall.EACCES) || errors.Is(pe.Err, syscall.ENOTDIR)) {\n        // stale/conflicting layout: wipe and retry once on a clean dir\n        os.RemoveAll(destDir)\n        os.MkdirAll(destDir, 0o755)\n        return flowfiles.ExtractTar(rc, destDir) // note: rc must be restartable\n    }\n    return err\n}","preventionTips":["Extract into a fresh per-request temp directory, then atomically move into place.","Pre-create destDir with correct ownership at service startup.","Monitor destination volume for space and permission drift after deploys."],"tags":["filesystem","tar","extract","mkdir"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}