{"record":{"id":"3fd4df71deb197f5","repo":"windmill-labs/windmill","slug":"error-saving-theme-at-resource-theme-path-you","errorCode":null,"errorMessage":"Error saving theme at resource ${theme.path}, you do not have enough permission","messagePattern":"Error saving theme at resource (.+?), you do not have enough permission","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/apps/editor/componentsPanel/themeUtils.ts","lineNumber":27,"sourceCode":"\t\tname: string\n\t}\n}\n\nexport const DEFAULT_THEME: string = 'f/app_themes/theme_0'\n\nexport async function createTheme(workspace: string, theme: Theme): Promise<string> {\n\tconst createThemeRequest = {\n\t\tworkspace,\n\t\trequestBody: {\n\t\t\t...theme,\n\t\t\tresource_type: 'app_theme',\n\t\t\tvalue: theme.value || ''\n\t\t}\n\t}\n\ttry {\n\t\treturn await ResourceService.createResource(createThemeRequest)\n\t} catch (e) {\n\t\tthrow Error(`Error saving theme at resource ${theme.path}, you do not have enough permission`)\n\t}\n}\n\nexport async function getTheme(\n\tworkspace: string,\n\tpath: string\n): Promise<{\n\tvalue?: string | undefined\n\tname: string\n}> {\n\ttry {\n\t\treturn AppService.getPublicResource({\n\t\t\tworkspace,\n\t\t\tpath\n\t\t}) as any\n\t} catch (e) {\n\t\tsendUserToast(`Theme not found ${path}`)\n\t\treturn {","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/apps/editor/componentsPanel/themeUtils.ts#L9-L45","documentation":"`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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nawait createTheme({ path: 'f/admin/company_theme', ... })\n// after\nawait createTheme({ path: 'u/myuser/company_theme', ... }) // path writable by current user","handlingStrategy":"try-catch","validationCode":"// 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.","typeGuard":null,"tryCatchPattern":"try {\n  await createTheme(theme)\n} catch (e) {\n  if (String(e.message).includes('you do not have enough permission')) {\n    toast.error('Cannot save theme: no write access at ' + theme.path + '. Pick a path in your user folder or ask an admin for access.')\n  } else throw e\n}","preventionTips":["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"],"tags":["permissions","theme","resource","api-error"],"backgroundTag":"insufficient-permissions","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}