{"record":{"id":"6205e8f5b5f9de8d","repo":"abhigyanpatwari/GitNexus","slug":"unknown-key-key-in-gitnexus-rc-filename","errorCode":null,"errorMessage":"Unknown key \"${key}\" in ${GITNEXUS_RC_FILENAME}. ${ALLOWED_KEYS_HINT}","messagePattern":"Unknown key \"(.+?)\" in (.+?)\\. (.+?)","errorType":"validation","errorClass":"GitNexusRcError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/cli/analyze-config.ts","lineNumber":337,"sourceCode":" * Normalize one level (flat top-level or the nested `analyze` block) into a\n * partial `AnalyzeOptions`. Rejects unknown keys and two aliases that configure\n * the same option at the same level.\n */\nconst normalizeLevel = (\n  obj: Record<string, unknown>,\n  { allowNestedKey }: { allowNestedKey: boolean },\n): Partial<AnalyzeOptions> => {\n  const out: Partial<AnalyzeOptions> = {};\n  const setBy = new Map<keyof AnalyzeOptions, string>();\n\n  for (const [key, value] of Object.entries(obj)) {\n    if (allowNestedKey && key === NESTED_KEY) continue; // handled separately\n    // `Object.hasOwn`, not a truthiness check: a plain-object lookup like\n    // `KEY_SPECS[\"__proto__\"]` returns an inherited member (Object.prototype,\n    // truthy) and would slip past `if (!spec)`, hitting the wrong error branch\n    // instead of the documented \"Unknown key\" message (#1996 tri-review P3).\n    if (!Object.hasOwn(KEY_SPECS, key)) {\n      throw new GitNexusRcError(\n        `Unknown key \"${key}\" in ${GITNEXUS_RC_FILENAME}. ${ALLOWED_KEYS_HINT}`,\n      );\n    }\n    const spec = KEY_SPECS[key];\n    const prev = setBy.get(spec.target);\n    if (prev && prev !== key) {\n      throw new GitNexusRcError(\n        `${GITNEXUS_RC_FILENAME}: \"${prev}\" and \"${key}\" both configure the same option; set only one.`,\n      );\n    }\n    setBy.set(spec.target, key);\n    (out as Record<string, unknown>)[spec.target] = normalizeValue(spec.kind, value, key);\n  }\n\n  return out;\n};\n\n/**","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/cli/analyze-config.ts#L319-L355","documentation":".gitnexusrc only accepts a fixed key set (the message embeds ALLOWED_KEYS_HINT listing them, plus the nested \"analyze\" object). Any key not in KEY_SPECS — including inherited prototype names like __proto__, which Object.hasOwn explicitly filters — throws this GitNexusRcError during loadAnalyzeConfig.","triggerScenarios":"A typo (\"skipAgentMd\", \"default_branch\"), an invented key (\"verbose\": true), or a key placed one level too deep (e.g. inside \"analyze\" a key that only exists flat, or vice versa where not allowed); also duplicate-concept keys are fine individually but unknown ones never are.","commonSituations":"Upgrading GitNexus and using keys documented for a different version; converting settings from another tool's config format; editors auto-completing wrong key names; CI templates drift.","solutions":["Read the Allowed-keys list printed in the error and rename/remove the unknown key","Check for spelling: e.g. defaultBranch/branch, skipAgentsMd/skipContextFiles/skipAiContext, skipSkills, pdg, indexOnly, stats/noStats, embeddings, dropEmbeddings, name, allowDuplicateName, maxFileSize, workerTimeout, walCheckpointThreshold, workers, embeddingThreads, embeddingBatchSize, embeddingSubBatchSize, embeddingDevice, fetchWrappers, embeddingBaseUrl, embeddingModel","Keys may also live inside a nested \"analyze\" object — group them there if you prefer"],"exampleFix":"// before (.gitnexusrc)\n{\"default_branch\": \"develop\", \"verbose\": true}\n// after\n{\"defaultBranch\": \"develop\"}","handlingStrategy":"validation","validationCode":"import { readFileSync } from 'node:fs';\nconst ALLOWED = new Set(['defaultBranch','branch','skipAgentsMd','skipContextFiles','skipAiContext','skipSkills','pdg','indexOnly','stats','noStats','embeddings','dropEmbeddings','name','allowDuplicateName','maxFileSize','workerTimeout','walCheckpointThreshold','workers','embeddingThreads','embeddingBatchSize','embeddingSubBatchSize','embeddingDevice','fetchWrappers','embeddingBaseUrl','embeddingModel','analyze']);\nconst rc = JSON.parse(readFileSync('.gitnexusrc', 'utf8'));\nconst unknown = Object.keys(rc).filter((k) => !ALLOWED.has(k));\nif (unknown.length) throw new Error(`Unknown .gitnexusrc keys: ${unknown.join(', ')}`);","typeGuard":"const isKnownRcKey = (k: string): boolean => ALLOWED.has(k);","tryCatchPattern":"catch (err) {\n  if (err instanceof GitNexusRcError && err.message.includes('Unknown key')) {\n    // the message already lists every allowed key — diff your file against it\n  }\n}","preventionTips":["Pin .gitnexusrc to the key list from the error's Allowed-keys hint","After upgrading GitNexus, re-check renamed keys before committing","Use Object.hasOwn-style lookups (not truthiness) if you replicate this check"],"tags":["config","validation","unknown-key","gitnexusrc"],"backgroundTag":"unknown-config-key","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"}