{"record":{"id":"cefb21cdf7cc568a","repo":"NousResearch/hermes-agent","slug":"theme-file-is-not-a-json-object","errorCode":null,"errorMessage":"Theme file is not a JSON object.","messagePattern":"Theme file is not a JSON object\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/desktop/src/themes/vscode.ts","lineNumber":83,"sourceCode":"\n/**\n * Parse a VS Code theme file. These ship as JSONC (line/block comments and\n * trailing commas), so a plain `JSON.parse` rejects most real-world files.\n * Strips comments + trailing commas, then parses. Throws on hard syntax errors.\n */\nexport function parseVscodeTheme(text: string): VscodeColorTheme {\n  const stripped = text\n    // Block comments.\n    .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n    // Line comments (not inside strings — naive but fine for theme files).\n    .replace(/(^|[^:\"'\\\\])\\/\\/[^\\n\\r]*/g, '$1')\n    // Trailing commas before } or ].\n    .replace(/,(\\s*[}\\]])/g, '$1')\n\n  const parsed: unknown = JSON.parse(stripped)\n\n  if (!parsed || typeof parsed !== 'object') {\n    throw new Error('Theme file is not a JSON object.')\n  }\n\n  return parsed as VscodeColorTheme\n}\n\nconst isDarkType = (raw: VscodeColorTheme, background: string): boolean => {\n  const type = (raw.type ?? '').toLowerCase()\n\n  if (type.includes('light')) {\n    return false\n  }\n\n  if (type === 'dark' || type === 'hc' || type === 'hc-black' || type.includes('dark')) {\n    return true\n  }\n\n  // No usable `type` — bucket by background luminance.\n  return luminance(background) < 0.4","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/apps/desktop/src/themes/vscode.ts#L65-L101","documentation":"Thrown by parseVscodeTheme when the theme file text, after stripping comments and trailing commas, parses to a non-object (or null) — i.e. JSON.parse succeeded but the top level is a number, string, array, or empty. The parser intentionally tolerates JSONC (comments, trailing commas) but still requires a top-level object.","triggerScenarios":"Feeding a .json theme file that is actually an array (token arrays like some semantic-token themes), an empty file, a plain string, or a file whose comment-stripping regex mangled the content into a non-object.","commonSituations":"Pointing the importer at a semantic token or icon manifest instead of a color theme file; a theme file containing URLs with '//' that the naive line-comment regex truncated, leaving invalid JSON remnants.","solutions":["Confirm the file is a VS Code color theme (JSON object with a 'colors' map), not a token array or manifest.","If the file contains '//' inside string values (URLs), escape or quote them so the naive comment-stripping does not corrupt the JSON.","Validate the raw file with a JSONC-aware linter before import."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function looksLikeThemeObject(text: string): boolean {\n  try {\n    // reuse same stripping rules minimally: must start with '{'\n    return text.trimStart().startsWith('{')\n  } catch { return false }\n}","typeGuard":"function isJsonObject(parsed: unknown): parsed is Record<string, unknown> {\n  return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)\n}","tryCatchPattern":"try {\n  parseVscodeTheme(text)\n} catch (e) {\n  if (e instanceof Error && e.message === 'Theme file is not a JSON object.')\n    rejectFile('Expected a JSON object theme file')\n  else if (e instanceof SyntaxError) rejectFile('Theme file is not valid JSON/JSONC')\n  else throw e\n}","preventionTips":["Reject files whose first non-space character is '[' (token arrays) before parsing.","Prefer theme files referenced by contributes.themes[].path over arbitrary JSON in the extension.","Escape '//' inside string literals (URLs) or validate with a JSONC parser first."],"tags":["desktop","themes","vscode","json-parse"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}