windmill-labs/windmill · error · Error

Missing root folder

Error message

Missing root folder

What it means

In folder-only uploads, uploadFileToS3() derives the root folder as the first path segment of the relative path. If that segment is empty (e.g. relativePath starts with '/' or is just '/'), it throws 'Missing root folder'.

Source

Thrown at frontend/src/lib/components/common/fileUpload/FileUpload.svelte:192

	}

	let uniqueFolderPrefix = getRandomFolderPrefix()
	let uploadedFolderRoot: string | undefined = undefined

	async function uploadFileToS3(fileToUpload: File & { path?: string }, fileToUploadKey: string) {
		if (fileToUpload === undefined || fileToUploadKey === undefined) {
			return
		}
		let path: string | undefined = undefined
		let fileExtension: string | undefined = undefined
		if (folderOnly) {
			const relativePath = fileToUpload.webkitRelativePath || fileToUpload.path
			if (!relativePath) {
				throw new Error('Missing file relative path')
			}
			const rootFolder = relativePath.split('/')[0]
			if (!rootFolder) {
				throw new Error('Missing root folder')
			}
			if (uploadedFolderRoot && rootFolder !== uploadedFolderRoot) {
				throw new Error('Uploading a file in a different root folder than the previous files')
			} else {
				uploadedFolderRoot = rootFolder
			}
			path = uniqueFolderPrefix + relativePath
		} else if (randomFileKey) {
			fileExtension = fileToUpload.name.split('.').pop()
			if (emptyString(fileExtension)) {
				fileExtension = undefined
			}
		} else {
			path =
				typeof pathTransformer == 'function'
					? ((await pathTransformer?.({
							file: fileToUpload
						})) ?? fileToUploadKey)

View on GitHub (pinned to e474e8803c)

Solutions

  1. Ensure each file's relative path starts with the folder name (e.g. 'root/sub/file.txt'), not with '/'
  2. Normalize the path before upload: strip leading slashes or prepend a root name
  3. Re-select the folder with the directory picker to regenerate correct paths

Example fix

// before
file.path = '/root/a.txt' // root is ''
// after
file.path = 'root/a.txt'
Defensive patterns

Strategy: validation

Validate before calling

const rel = file.webkitRelativePath || file.path
const root = rel?.split('/')[0]
if (folderOnly && !root) {
  console.error('Relative path must start with a root folder name')
}

Type guard

function hasRootFolder(f: File & {webkitRelativePath?: string; path?: string}): boolean {
  const rel = f.webkitRelativePath || f.path || ''
  return rel.split('/')[0] !== ''
}

Try / catch

try {
  await uploadFileToS3(file)
} catch (e) {
  if (e.message === 'Missing root folder') {
    console.error('Normalize paths so the first segment is the root folder', e)
  } else throw e
}

Prevention

When it happens

Trigger: A file whose webkitRelativePath/path has an empty first segment, so relativePath.split('/')[0] is ''.

Common situations: Manually crafted paths like '/sub/file.txt'; synthetic File objects with a leading-slash path; odd drag-and-drop entry paths.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/18b6462bbf0f844c. Report an issue: GitHub.