{"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":409,"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":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/cli/analyze-config.ts#L391-L427","documentation":"The nested `analyze` key is present in `.gitnexusrc` but its value is not a JSON object — it is an array, string, number, boolean, or null. The nested block must itself be an object holding the same allowed keys.","triggerScenarios":"Setting { \"analyze\": [] }, { \"analyze\": \"develop\" }, or { \"analyze\": null }.","commonSituations":"Confusing the nested `analyze` block with a list; templating that emits an array for the nested section; setting null intending to disable the nested block (omit the key instead).","solutions":["Make the `analyze` value a JSON object, e.g. { \"analyze\": { \"defaultBranch\": \"develop\" } }.","Omit the `analyze` key entirely if you have no nested overrides."],"exampleFix":"// before\n{\"analyze\": []}\n// after\n{\"analyze\": {\"defaultBranch\": \"develop\"}}","handlingStrategy":"validation","validationCode":"if (Object.prototype.hasOwnProperty.call(parsed, 'analyze')) {\n  const nested = parsed.analyze;\n  if (nested === null || typeof nested !== 'object' || Array.isArray(nested)) {\n    throw new Error('.gitnexusrc \"analyze\" must be a JSON object');\n  }\n}","typeGuard":"const isAnalyzeBlock = (v) =>\n  v !== null && typeof v === 'object' && !Array.isArray(v);","tryCatchPattern":null,"preventionTips":["Make the `analyze` value an object, not an array.","Omit `analyze` when you have no nested overrides."],"tags":["config","gitnexusrc","json","validation"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}