{"record":{"id":"f03d2924c9e4a7c0","repo":"infiniflow/ragflow","slug":"failed-to-list-directory-dirname","errorCode":null,"errorMessage":"Failed to list directory: ${dirName}","messagePattern":"Failed to list directory: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/src/pages/skills/hooks.ts","lineNumber":873,"sourceCode":"            const formData = new FormData();\n            formData.append('parent_id', parentId);\n            formData.append('file', file);\n            await fileManagerService.uploadFile(formData);\n            return;\n          }\n\n          // Navigate/create directory structure\n          let currentParentId = parentId;\n          for (let i = 0; i < pathParts.length - 1; i++) {\n            const dirName = pathParts[i];\n\n            // List current directory to check if subdirectory exists\n            const { data: listData } = await fileManagerService.listFile({\n              parent_id: currentParentId,\n            });\n\n            if (listData.code !== 0) {\n              throw new Error(`Failed to list directory: ${dirName}`);\n            }\n\n            const existingDir = listData.data?.files?.find(\n              (f: any) => f.name === dirName && f.type === 'folder',\n            );\n\n            if (existingDir) {\n              currentParentId = existingDir.id;\n            } else {\n              // Create subdirectory\n              const createRes = await fileManagerService.createFolder({\n                name: dirName,\n                type: 'folder',\n                parent_id: currentParentId,\n              });\n\n              if (createRes.data.code !== 0) {\n                throw new Error(`Failed to create directory: ${dirName}`);","sourceCodeStart":855,"sourceCodeEnd":891,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/web/src/pages/skills/hooks.ts#L855-L891","documentation":"Thrown in web/src/pages/skills/hooks.ts:873 during recursive upload: while walking the file's webkitRelativePath directory chain, a fileManagerService.listFile on the current parent returns code !== 0. The walker needs to know whether each subdirectory already exists before creating it; if the listing fails, the traversal aborts with the failing directory name embedded in the message.","triggerScenarios":"Uploading a skill with nested folders (src/, docs/…) where a mid-traversal listFile fails because the parent folder was deleted concurrently; token expiry during a long multi-file upload; backend file-manager transient error; currentParentId undefined after a previous step silently failed.","commonSituations":"Large skill packages with deep folder trees outlasting the auth session. Another user reorganizing the same space mid-upload. Flaky backend under load.","solutions":["Include the response code/message alongside dirName in the error","Retry the listFile once after a short delay before failing (transient errors)","Re-authenticate and restart the upload for very large trees","Check the file manager UI to confirm the parent chain still exists before retrying"],"exampleFix":"// before\nif (listData.code !== 0) {\n  throw new Error(`Failed to list directory: ${dirName}`);\n}\n\n// after\nif (listData.code !== 0) {\n  throw new Error(\n    `Failed to list directory ${dirName} (code ${listData.code}): ${\n      listData.message || 'unknown error'\n    }`,\n  );\n}","handlingStrategy":"retry","validationCode":"const canList = async (parentId: string) =>\n  parentId != null &&\n  (await fileManagerService.listFile({ parent_id: parentId })).data.code === 0;","typeGuard":null,"tryCatchPattern":"try {\n  const { data } = await fileManagerService.listFile({ parent_id });\n  if (data.code !== 0) throw new Error(data.message);\n} catch (e) {\n  await backoffRetry(); // transient under load\n}","preventionTips":["Batch the whole folder tree creation up front, then upload files, to shorten the traversal window","Refresh auth before large multi-level uploads"],"tags":["skills","file-manager","upload","recursive-traversal"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}