{"record":{"id":"8b95ba2218edae49","repo":"windmill-labs/windmill","slug":"uploading-a-file-in-a-different-root-folder-than-t","errorCode":null,"errorMessage":"Uploading a file in a different root folder than the previous files","messagePattern":"Uploading a file in a different root folder than the previous files","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/common/fileUpload/FileUpload.svelte","lineNumber":195,"sourceCode":"\tlet uploadedFolderRoot: string | undefined = undefined\n\n\tasync function uploadFileToS3(fileToUpload: File & { path?: string }, fileToUploadKey: string) {\n\t\tif (fileToUpload === undefined || fileToUploadKey === undefined) {\n\t\t\treturn\n\t\t}\n\t\tlet path: string | undefined = undefined\n\t\tlet fileExtension: string | undefined = undefined\n\t\tif (folderOnly) {\n\t\t\tconst relativePath = fileToUpload.webkitRelativePath || fileToUpload.path\n\t\t\tif (!relativePath) {\n\t\t\t\tthrow new Error('Missing file relative path')\n\t\t\t}\n\t\t\tconst rootFolder = relativePath.split('/')[0]\n\t\t\tif (!rootFolder) {\n\t\t\t\tthrow new Error('Missing root folder')\n\t\t\t}\n\t\t\tif (uploadedFolderRoot && rootFolder !== uploadedFolderRoot) {\n\t\t\t\tthrow new Error('Uploading a file in a different root folder than the previous files')\n\t\t\t} else {\n\t\t\t\tuploadedFolderRoot = rootFolder\n\t\t\t}\n\t\t\tpath = uniqueFolderPrefix + relativePath\n\t\t} else if (randomFileKey) {\n\t\t\tfileExtension = fileToUpload.name.split('.').pop()\n\t\t\tif (emptyString(fileExtension)) {\n\t\t\t\tfileExtension = undefined\n\t\t\t}\n\t\t} else {\n\t\t\tpath =\n\t\t\t\ttypeof pathTransformer == 'function'\n\t\t\t\t\t? ((await pathTransformer?.({\n\t\t\t\t\t\t\tfile: fileToUpload\n\t\t\t\t\t\t})) ?? fileToUploadKey)\n\t\t\t\t\t: fileToUploadKey\n\t\t}\n\t\tconst uploadData: FileUploadData = {","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/common/fileUpload/FileUpload.svelte#L177-L213","documentation":"uploadFileToS3() enforces that all files in a folder-only upload share one root folder, tracked in uploadedFolderRoot. A file whose root differs from previously uploaded files throws 'Uploading a file in a different root folder than the previous files'.","triggerScenarios":"Uploading/mixing files from two different selected folders in the same FileUpload instance (e.g. selecting another folder after a first batch, or adding stray files with a different top-level directory).","commonSituations":"Selecting a second folder into the same component mid-batch; merging directory uploads in a loop; component state (uploadedFolderRoot) persisting between picks.","solutions":["Clear/reset the upload component (and its uploadedFolderRoot state) before starting a new folder batch","Upload one folder per batch, or use separate FileUpload instances per root","If mixing is intended, disable folderOnly mode or move files under a common root"],"exampleFix":"// before\n// uploading 'dirA/a.txt' then 'dirB/b.txt' into same component\n// after\nuploadedFolderRoot = undefined // reset before new batch, or keep one root per batch","handlingStrategy":"try-catch","validationCode":"if (uploadedFolderRoot) {\n  const root = (file.webkitRelativePath || file.path).split('/')[0]\n  if (root !== uploadedFolderRoot) {\n    console.error('Reset the upload or use a component per root folder')\n  }\n}","typeGuard":"function sameRoot(f: File, currentRoot: string | undefined): boolean {\n  const root = (f.webkitRelativePath || (f as any).path || '').split('/')[0]\n  return !currentRoot || root === currentRoot\n}","tryCatchPattern":"try {\n  await uploadFileToS3(file)\n} catch (e) {\n  if (e.message.startsWith('Uploading a file in a different root folder')) {\n    uploadedFolderRoot = undefined // reset state, restart the batch\n  } else throw e\n}","preventionTips":["One folder per upload batch; reset state between picks","Use separate FileUpload components per folder","Validate all selected files share a root before starting the batch"],"tags":["file-upload","s3","state-conflict"],"backgroundTag":"mixed-upload-root-folders","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}