windmill-labs/windmill · error

Invalid empty file extension (make sure it is selected)

Error message

Invalid empty file extension (make sure it is selected)

What it means

The resources page's addResourceType validates the new resource-type form before calling ResourceService.createResourceType. For a non-fileset type, an empty formatExtension is rejected with this error because the backend would create a file resource type with no extension.

Source

Thrown at frontend/src/routes/(root)/(logged)/resources/+page.svelte:328

					...x
				}
			}
		)
		loading.types = false
	}

	async function deleteResource(path: string, account?: number): Promise<void> {
		if (account) {
			OauthService.disconnectAccount({ workspace: $workspaceStore!, id: account })
		}
		await ResourceService.deleteResource({ workspace: $workspaceStore!, path })
		reload()
	}

	async function addResourceType(): Promise<void> {
		if (!newResourceType.isFileset) {
			if (newResourceType.formatExtension === '') {
				throw new Error('Invalid empty file extension (make sure it is selected)')
			}
			if (!validateFileExtension(newResourceType.formatExtension ?? 'txt')) {
				throw new Error('Invalid file extension')
			}
		}
		await ResourceService.createResourceType({
			workspace: $workspaceStore!,
			requestBody: {
				name: (disableCustomPrefix ? '' : 'c_') + newResourceType.name,
				schema: newResourceType.schema,
				description: newResourceType.description,
				format_extension: newResourceType.formatExtension,
				is_fileset: newResourceType.isFileset
			}
		})
		resourceTypeDrawer?.closeDrawer?.()
		sendUserToast('Resource type created')
		loadResourceTypes()

View on GitHub (pinned to e474e8803c)

Solutions

  1. Select a file extension in the resource-type form before submitting
  2. Tick the 'fileset' option instead if the type has no single extension
  3. Ensure the form initializes formatExtension to a sensible default (e.g. 'txt') when not a fileset

Example fix

// before
formatExtension: '',
isFileset: false
// after
formatExtension: 'txt', // or select a value in the dropdown
isFileset: false
Defensive patterns

Strategy: validation

Validate before calling

if (!newResourceType.isFileset && (newResourceType.formatExtension ?? '') === '') {
  sendUserToast('Select a file extension for this resource type', true)
  return
}
await addResourceType()

Type guard

function hasExtension(rt: { isFileset: boolean; formatExtension?: string }): boolean {
  return rt.isFileset || (typeof rt.formatExtension === 'string' && rt.formatExtension.length > 0)
}

Try / catch

try {
  await addResourceType()
} catch (e) {
  if (e.message.includes('Invalid empty file extension')) {
    sendUserToast('Pick a file extension in the form', true)
  } else throw e
}

Prevention

When it happens

Trigger: Submitting the 'add resource type' form with 'is fileset' unchecked while the file-format extension dropdown/input was left empty (''), e.g. user chose format 'Custom' but never picked an extension.

Common situations: Forgetting to select the file extension in the create-resource-type drawer; a form state reset that cleared the extension while isFileset stayed false; pasting a config where extension is empty string instead of undefined.

Related errors


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