{"record":{"id":"8e0ab3f85492f809","repo":"vxcontrol/pentagi","slug":"reading-container-cache-w","errorCode":null,"errorMessage":"reading container cache: %w","messagePattern":"reading container cache: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/flowfiles/files.go","lineNumber":64,"sourceCode":"\tFiles []File\n\tTotal uint64\n}\n\n// TarEntry describes a local regular file to include in a TAR archive.\ntype TarEntry struct {\n\tLocalPath string\n\tTarPath   string\n}\n\nfunc List(dataDir string, flowID uint64) (Files, error) {\n\tuploadsEntries, err := ListDirEntries(FlowUploadsDir(dataDir, flowID), UploadsDirName)\n\tif err != nil {\n\t\treturn Files{}, fmt.Errorf(\"reading uploads cache: %w\", err)\n\t}\n\n\tcontainerEntries, err := ListDirEntriesRecursive(FlowContainerDir(dataDir, flowID), ContainerDirName)\n\tif err != nil {\n\t\treturn Files{}, fmt.Errorf(\"reading container cache: %w\", err)\n\t}\n\n\tresourcesEntries, err := ListDirEntriesRecursive(FlowResourcesDir(dataDir, flowID), ResourcesDirName)\n\tif err != nil {\n\t\treturn Files{}, fmt.Errorf(\"reading resources cache: %w\", err)\n\t}\n\n\tfiles := append(uploadsEntries, containerEntries...)\n\tfiles = append(files, resourcesEntries...)\n\tSort(files)\n\treturn Files{\n\t\tFiles: files,\n\t\tTotal: uint64(len(files)),\n\t}, nil\n}\n\nfunc FlowDataDir(dataDir string, flowID uint64) string {\n\treturn filepath.Join(dataDir, fmt.Sprintf(\"flow-%d-data\", flowID))","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/flowfiles/files.go#L46-L82","documentation":"Same aggregation flow as the uploads variant: List() fails while recursively listing the per-flow container directory (ListDirEntriesRecursive on FlowContainerDir). The OS error is wrapped and returned to the caller.","triggerScenarios":"List(dataDir, flowID) with a container-dir that is missing, unreadable, or a symlink loop / permission problem encountered during recursion.","commonSituations":"Container file cache never populated for the flow; Docker container writes failed silently so the cache dir wasn't created; volume permission drift; partially deleted flow data.","solutions":["Ensure the container cache directory is created when the flow/container starts","Treat os.ErrNotExist as an empty result if an empty cache is a valid state","Check recursive-read permissions on FlowContainerDir(dataDir, flowID)","Verify the data volume mount for the container-facing cache"],"exampleFix":"// before\nreturn Files{}, fmt.Errorf(\"reading container cache: %w\", err)\n// after\nif os.IsNotExist(err) {\n    containerEntries = nil\n} else {\n    return Files{}, fmt.Errorf(\"reading container cache: %w\", err)\n}","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(files.FlowContainerDir(dataDir, flowID)); os.IsNotExist(err) {\n    os.MkdirAll(files.FlowContainerDir(dataDir, flowID), 0o755)\n}","typeGuard":"func isMissingContainerCache(err error) bool {\n    return strings.Contains(err.Error(), \"reading container cache\") && errors.Is(err, os.ErrNotExist)\n}","tryCatchPattern":"files, err := flowfiles.List(dataDir, flowID)\nif err != nil && strings.Contains(err.Error(), \"reading container cache\") {\n    if os.IsNotExist(err) { files = flowfiles.Files{} } else { return err }\n}","preventionTips":["Create the container cache dir when the flow's container starts","Handle empty caches as a normal state for new flows","Check permissions after any volume migration or backup restore","Watch disk/volume health for the data mount"],"tags":["filesystem","flowfiles","directory"],"backgroundTag":"directory-read-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}