{"record":{"id":"c580191d1883d2d5","repo":"NousResearch/hermes-agent","slug":"result-extensionid-does-not-contribute-any-co","errorCode":null,"errorMessage":"\"${result.extensionId}\" does not contribute any color themes.","messagePattern":"\"(.+?)\" does not contribute any color themes\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/desktop/src/themes/install.ts","lineNumber":40,"sourceCode":"  const { theme } = convertVscodeColorTheme(raw, opts)\n\n  return installUserTheme(theme)\n}\n\n/**\n * Fold every color theme an extension contributes into ONE desktop theme family.\n *\n * Many extensions ship a light *and* a dark variant (GitHub, Solarized, Winter\n * is Coming…). Rather than install them as separate flat entries — which made\n * the light/dark toggle a no-op and let \"install in dark mode\" land on the light\n * variant — we map the first light variant onto `colors` and the first dark\n * variant onto `darkColors`. The result is a single picker entry whose light/dark\n * toggle switches between the real variants. A single-variant extension fills\n * both slots with its one palette (the toggle is a no-op, as it must be).\n */\nexport function buildThemeFromMarketplace(result: DesktopMarketplaceThemeResult): DesktopTheme {\n  if (!result.themes.length) {\n    throw new Error(`\"${result.extensionId}\" does not contribute any color themes.`)\n  }\n\n  const variants = result.themes.map(file => {\n    const raw = parseVscodeTheme(file.contents)\n    const label = file.label || raw.name || result.displayName\n    const { mode, theme } = convertVscodeColorTheme(raw, { label, source: result.extensionId })\n\n    return { mode, palette: theme.colors, terminal: theme.terminal }\n  })\n\n  const fallback = variants[0]\n  const light = variants.find(variant => variant.mode === 'light') ?? fallback\n  const dark = variants.find(variant => variant.mode === 'dark') ?? fallback\n\n  // The terminal ANSI palette tracks the painted variant the same way colors do\n  // (light → terminal, dark → darkTerminal); each falls back to the other so a\n  // single-variant import still themes the terminal in both modes.\n  const terminal = light.terminal ?? dark.terminal","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/apps/desktop/src/themes/install.ts#L22-L58","documentation":"Thrown by buildThemeFromMarketplace when a successfully downloaded VS Code Marketplace extension contributes zero color themes (result.themes is empty). The installer expects the extension manifest to list at least one theme contribution; an extension that ships icons, snippets, or language packs only produces an empty array and this error.","triggerScenarios":"installVscodeThemeFromMarketplace(id) with a valid 'publisher.extension' id for an extension whose package.json has no contributes.themes entries (or whose themes the fetcher could not read).","commonSituations":"Installing an icon theme (e.g. Material Icon Theme) or a product extension (Prettier, ESLint) by id, mistaking it for a color theme; or a Marketplace metadata change that drops theme contribution info.","solutions":["Verify on the Marketplace page that the extension actually ships color themes (not just icon themes or tools).","Use the exact publisher.extension id of a known color theme (e.g. 'GitHub.github-vscode-theme').","If the extension should have themes, check the fetchMarketplace result — the API response may be truncated or the manifest unreadable; retry after app update."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function isColorThemeExtension(result: DesktopMarketplaceThemeResult): boolean {\n  return Array.isArray(result.themes) && result.themes.length > 0\n}","typeGuard":"function hasThemes(result: DesktopMarketplaceThemeResult): result is DesktopMarketplaceThemeResult & { themes: [ThemeFile, ...ThemeFile[]] } {\n  return result.themes.length > 0\n}","tryCatchPattern":"try {\n  await installVscodeThemeFromMarketplace(id)\n} catch (e) {\n  if (e instanceof Error && e.message.includes('does not contribute any color themes'))\n    showHint('Pick an extension that ships color themes')\n  else throw e\n}","preventionTips":["Filter the Marketplace picker to extensions whose package.json contributes.themes is non-empty.","Show extension type (color theme vs icon theme) before install.","Prefer curated/pinned theme extension ids in the UI."],"tags":["desktop","themes","vscode","marketplace"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}