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
- Check the resource path's owner group and add your user/group write permission on that resource prefix in workspace settings > groups
- Save the theme to a path your account can write (e.g. under u/<username>/) instead of a shared/admin path
- Log in again — an expired token produces 401 that surfaces as this same message
- 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
- Save themes under a path your group can write (u/<username>/...)
- Verify resource-path group permissions in workspace settings before saving
- Re-login if the session token may be expired
- Check whether the resource already exists and edit it instead of creating
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
- Failed to create schedule "${requestBody.path}": ${formatToo
- Failed to create ${triggerConfig.label} "${requestBody.path}
- Failed to create flow ${remotePath}: ${e.body ?? e.message}
- npm exited with ${exitCode === null ? "a signal" : `code ${e
- PlanWriteRefusedError
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/3fd4df71deb197f5.
Report an issue: GitHub.