windmill-labs/windmill · error · Error

Error saving theme at resource ${theme.path}, you do not hav

Error message

Error saving theme at resource ${theme.path}, you do not have enough permission

What it means

`createTheme` in themeUtils.ts wraps any failure of `ResourceService.createResource` into this message. Themes are stored as resources at `theme.path`, and the backend rejects the create when the current token lacks permission to write at that path — typically a missing `resources` write grant or a path outside allowed prefixes for the user's group.

Source

Thrown at frontend/src/lib/components/apps/editor/componentsPanel/themeUtils.ts:27

		name: string
	}
}

export const DEFAULT_THEME: string = 'f/app_themes/theme_0'

export async function createTheme(workspace: string, theme: Theme): Promise<string> {
	const createThemeRequest = {
		workspace,
		requestBody: {
			...theme,
			resource_type: 'app_theme',
			value: theme.value || ''
		}
	}
	try {
		return await ResourceService.createResource(createThemeRequest)
	} catch (e) {
		throw Error(`Error saving theme at resource ${theme.path}, you do not have enough permission`)
	}
}

export async function getTheme(
	workspace: string,
	path: string
): Promise<{
	value?: string | undefined
	name: string
}> {
	try {
		return AppService.getPublicResource({
			workspace,
			path
		}) as any
	} catch (e) {
		sendUserToast(`Theme not found ${path}`)
		return {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Check the resource path's owner group and add your user/group write permission on that resource prefix in workspace settings > groups
  2. Save the theme to a path your account can write (e.g. under u/<username>/) instead of a shared/admin path
  3. Log in again — an expired token produces 401 that surfaces as this same message
  4. If the resource already exists, edit it (needs edit permission) rather than creating it

Example fix

// before
await createTheme({ path: 'f/admin/company_theme', ... })
// after
await createTheme({ path: 'u/myuser/company_theme', ... }) // path writable by current user
Defensive patterns

Strategy: try-catch

Validate before calling

// Themes are resources: check the path prefix you can write to (e.g. u/<username>/) and confirm you are logged into the right workspace before saving.

Try / catch

try {
  await createTheme(theme)
} catch (e) {
  if (String(e.message).includes('you do not have enough permission')) {
    toast.error('Cannot save theme: no write access at ' + theme.path + '. Pick a path in your user folder or ask an admin for access.')
  } else throw e
}

Prevention

When it happens

Trigger: Calling createTheme (invoked from the components panel theme message handler) while the workspace/worker token cannot create a resource at theme.path: path owned by another group, admin-only prefix, or the underlying API returned 403/401/409 (e.g. resource already exists without edit rights).

Common situations: A non-admin user trying to save a theme at an admin-owned path; workspace switched so the token belongs to a workspace where the path is not writable; theme.path typo pointing at a restricted folder; expired session token causing 401 that is misreported as a permission error.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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