windmill-labs/windmill · error · Error

Missing file relative path

Error message

Missing file relative path

What it means

FileUpload.svelte's uploadFileToS3() computes each file's path for folder uploads from file.webkitRelativePath || file.path. When folderOnly is set and neither property exists, it throws 'Missing file relative path'.

Source

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

	function getRandomFolderPrefix(): string {
		const now = Date.now()
		const randomNum = Math.floor(Math.random() * 65536)
		return `windmill_uploads/upload_${now}_${randomNum}/`
	}

	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 =

View on GitHub (pinned to e474e8803c)

Solutions

  1. Select the folder via the directory input (webkitdirectory) so webkitRelativePath is populated
  2. For drag-and-drop, use DataTransferItem.webkitGetAsEntry() to reconstruct relative paths before uploading
  3. If uploading individual files, disable folderOnly mode

Example fix

// before
const file = new File([blob], 'a.txt') // no webkitRelativePath
// after
// let user pick via <input type="file" webkitdirectory> so file.webkitRelativePath = 'root/a.txt'
Defensive patterns

Strategy: validation

Validate before calling

const rel = (file as any).webkitRelativePath || (file as any).path
if (folderOnly && !rel) {
  console.error('Folder upload requires webkitRelativePath; use a webkitdirectory input')
}

Type guard

function hasRelativePath(f: File): f is File & {webkitRelativePath: string} {
  return f.webkitRelativePath !== ''
}

Try / catch

try {
  await uploadFileToS3(file)
} catch (e) {
  if (e.message === 'Missing file relative path') {
    console.error('Use the directory picker for folder uploads', e)
  } else throw e
}

Prevention

When it happens

Trigger: Uploading with folder-only mode using files that were not selected via a directory picker (drag-and-drop or programmatic File objects without webkitRelativePath/path).

Common situations: Files added via drag-and-drop (webkitdirectory metadata absent); constructing File objects in tests or code and passing them to the uploader; browser privacy/compat removing the path property.

Related errors


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