{"record":{"id":"297e9ed50180cccf","repo":"NousResearch/hermes-agent","slug":"theme-name-collides-with-a-built-in-theme","errorCode":null,"errorMessage":"\"${theme.name}\" collides with a built-in theme.","messagePattern":"\"(.+?)\" collides with a built-in theme\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/desktop/src/themes/user-themes.ts","lineNumber":92,"sourceCode":"    return {}\n  }\n}\n\nfunction persist(record: Record<string, DesktopTheme>) {\n  try {\n    window.localStorage.setItem(USER_THEMES_KEY, JSON.stringify(record))\n  } catch {\n    // Best-effort: a restricted storage context shouldn't break theming.\n  }\n}\n\n/** Reactive map of installed user themes, keyed by slug. */\nexport const $userThemes = atom<Record<string, DesktopTheme>>(typeof window === 'undefined' ? {} : readStored())\n\n/** Install (or replace) a user theme. Returns the stored theme. */\nexport function installUserTheme(theme: DesktopTheme): DesktopTheme {\n  if (BUILTIN_THEMES[theme.name]) {\n    throw new Error(`\"${theme.name}\" collides with a built-in theme.`)\n  }\n\n  if (!isValidTheme(theme)) {\n    throw new Error('Theme is missing required colors.')\n  }\n\n  const next = { ...$userThemes.get(), [theme.name]: theme }\n  $userThemes.set(next)\n  persist(next)\n\n  return theme\n}\n\n/** Remove a user theme by slug. No-op for unknown / built-in names. */\nexport function removeUserTheme(name: string): void {\n  const current = $userThemes.get()\n\n  if (!current[name]) {","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/apps/desktop/src/themes/user-themes.ts#L74-L110","documentation":"Thrown by installUserTheme when the theme's name matches a built-in theme (BUILTIN_THEMES lookup by name). User themes are stored keyed by name alongside built-ins; allowing a collision would let an installed theme shadow or be confused with a built-in, so installation is refused before any state or localStorage write.","triggerScenarios":"Installing a user/imported theme whose name field equals a built-in theme name (e.g. a converted VS Code theme labeled 'default', 'mono', 'slate', or 'ares').","commonSituations":"Importing a VS Code theme whose display name happens to match a Hermes built-in, or a custom JSON theme copied from a built-in without renaming.","solutions":["Rename the theme (its name field / label) to something unique before installing.","If you want to override a built-in look, create a copy with a distinct name and edit its colors.","Pre-check BUILTIN_THEMES[theme.name] in your own code and prompt for a new name."],"exampleFix":"// before\ninstallUserTheme({ ...theme, name: 'slate' })\n\n// after\ninstallUserTheme({ ...theme, name: 'slate-custom' })","handlingStrategy":"validation","validationCode":"import { BUILTIN_THEMES } from '.../themes'\n\nfunction isNameFree(name: string): boolean {\n  return !BUILTIN_THEMES[name]\n}","typeGuard":"function isInstallableName(name: string): boolean {\n  return !BUILTIN_THEMES[name]\n}","tryCatchPattern":"try {\n  installUserTheme(theme)\n} catch (e) {\n  if (e instanceof Error && e.message.includes('collides with a built-in'))\n    promptRename(theme)\n  else throw e\n}","preventionTips":["Auto-suffix imported theme names (e.g. 'slate (imported)') when they match built-ins.","Check BUILTIN_THEMES before showing an install button.","Namespace converted VS Code themes by extension id to avoid collisions."],"tags":["desktop","themes","naming","validation"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}