{"record":{"id":"c297f8dfd0921d09","repo":"abhigyanpatwari/GitNexus","slug":"gitnexus-rc-filename-nested-key-must-be-a","errorCode":null,"errorMessage":"${GITNEXUS_RC_FILENAME} \"${NESTED_KEY}\" must be a JSON object.","messagePattern":"(.+?) \"(.+?)\" must be a JSON object\\.","errorType":"validation","errorClass":"GitNexusRcError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/cli/analyze-config.ts","lineNumber":417,"sourceCode":"  } catch (err) {\n    throw new GitNexusRcError(\n      `${GITNEXUS_RC_FILENAME} is not valid JSON: ${(err as Error).message}. ` +\n        `Expected a JSON object such as {\"defaultBranch\": \"develop\", \"skipContextFiles\": true}.`,\n    );\n  }\n\n  if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n    throw new GitNexusRcError(`${GITNEXUS_RC_FILENAME} must contain a JSON object.`);\n  }\n\n  const obj = parsed as Record<string, unknown>;\n  const flat = normalizeLevel(obj, { allowNestedKey: true });\n\n  let nested: Partial<AnalyzeOptions> = {};\n  if (Object.prototype.hasOwnProperty.call(obj, NESTED_KEY)) {\n    const nestedRaw = obj[NESTED_KEY];\n    if (nestedRaw === null || typeof nestedRaw !== 'object' || Array.isArray(nestedRaw)) {\n      throw new GitNexusRcError(`${GITNEXUS_RC_FILENAME} \"${NESTED_KEY}\" must be a JSON object.`);\n    }\n    nested = normalizeLevel(nestedRaw as Record<string, unknown>, { allowNestedKey: false });\n  }\n\n  // Nested `analyze` block overrides flat top-level keys for the same option.\n  return { ...flat, ...nested };\n}\n\n/**\n * Merge CLI options over `.gitnexusrc` defaults. CLI wins whenever it provides a\n * value — including an explicit `false` (so an explicit CLI off-switch beats a\n * config `true`). Config fills only the genuinely-unset (`undefined`) options.\n *\n * `stats` is special: Commander always materializes it (`true` by default,\n * `false` only when `--no-stats` is passed), so plain `??` can't tell \"default\n * on\" from \"explicitly on\". The rule is: a passed `--no-stats` (`stats: false`)\n * always wins; otherwise the config value applies. There is intentionally no\n * `--stats` counter-flag, so config can only turn stats off, not force it back","sourceCodeStart":399,"sourceCodeEnd":435,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/cli/analyze-config.ts#L399-L435","documentation":"The optional nested \"analyze\" block in .gitnexusrc must itself be a JSON object. If the key exists but its value is an array, null, or a scalar, loadAnalyzeConfig throws before normalizing that level's keys.","triggerScenarios":"{\"analyze\": []}, {\"analyze\": null}, or {\"analyze\": \"workers=4\"} in .gitnexusrc; also a nested block mistakenly placed two levels deep so the value ends up a string.","commonSituations":"Assuming \"analyze\" takes a string of CLI flags; scaffolding with an empty array; merging configs where the nested object got replaced by a list.","solutions":["Make the block an object of allowed keys: {\"analyze\": {\"workers\": 8}}","If you meant flags-as-string, translate them into real keys instead","Empty nested block {} is legal but pointless — either populate it or drop it"],"exampleFix":"// before (.gitnexusrc)\n{\"analyze\": \"--workers 8\"}\n// after\n{\"analyze\": {\"workers\": 8}}","handlingStrategy":"type-guard","validationCode":"if (rc.analyze !== undefined && (rc.analyze === null || typeof rc.analyze !== 'object' || Array.isArray(rc.analyze))) {\n  throw new Error('.gitnexusrc \"analyze\" must be a JSON object of option keys');\n}","typeGuard":"const isNestedAnalyzeBlock = (v: unknown): v is Record<string, unknown> =>\n  v !== null && typeof v === 'object' && !Array.isArray(v);","tryCatchPattern":"catch (err) {\n  if (err instanceof GitNexusRcError && err.message.includes('\"analyze\" must be a JSON object')) {\n    // convert flag strings into real keys inside the block\n  }\n}","preventionTips":["The \"analyze\" block holds option keys, not a CLI flag string","Mirror the same key set as the flat level inside it"],"tags":["config","json","validation","gitnexusrc"],"backgroundTag":"config-type-mismatch","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}