abhigyanpatwari/GitNexus · error · GitNexusRcError
: " " and " " both configure the same option; set only one.
Error message
${GITNEXUS_RC_FILENAME}: "${prev}" and "${key}" both configure the same option; set only one. What it means
Several .gitnexusrc keys are aliases for the same underlying AnalyzeOptions target (branch→defaultBranch, skipContextFiles/skipAiContext→skipAgentsMd, noStats→stats). normalizeLevel tracks which physical key set each target; if two different aliases both appear at the same level, the config is ambiguous and rejected.
Solutions
- Delete one of the two aliases named in the message — the error quotes both keys explicitly
- Standardize the team's .gitnexusrc on one alias set and enforce it in review
- If you need per-command override, put the base value flat and the override in the nested "analyze" object (nested legitimately overrides flat)
Example fix
// before (.gitnexusrc)
{"defaultBranch": "main", "branch": "develop"}
// after
{"defaultBranch": "develop"} Defensive patterns
Strategy: validation
Validate before calling
const ALIAS_GROUPS: string[][] = [
['defaultBranch', 'branch'],
['skipAgentsMd', 'skipContextFiles', 'skipAiContext'],
['stats', 'noStats'],
];
const keys = new Set(Object.keys(rc));
for (const group of ALIAS_GROUPS) {
const present = group.filter((k) => keys.has(k));
if (present.length > 1) throw new Error(`Pick one of: ${present.join(', ')}`);
} Try / catch
catch (err) {
if (err instanceof GitNexusRcError && err.message.includes('both configure the same option')) {
// message names both keys; delete one of them
}
} Prevention
- Standardize the team on one alias per option and lint the others out
- Use the nested "analyze" object for overrides instead of mixing aliases flat
When it happens
Trigger: {"defaultBranch": "main", "branch": "develop"}; {"skipAgentsMd": true, "skipContextFiles": true}; {"stats": true, "noStats": true} — each pair collides on one target option; applies inside the nested "analyze" block too (flat vs nested across levels is allowed, nested wins).
Common situations: Merging rc files from two teams that each standardized on a different alias; incremental edits adding the newer alias without removing the old one; docs examples that mix aliases in one snippet.
Related errors
- must contain a JSON object.
- " " must be a JSON object.
- entries must all be strings.
- entries must not be empty.
- entry " " must be an identifier or member name (letters…
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-08-20).
Data as JSON: /api/errors/dbe91a6b37378d11.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/cli/analyze-config.ts:344
): Partial<AnalyzeOptions> => {
const out: Partial<AnalyzeOptions> = {};
const setBy = new Map<keyof AnalyzeOptions, string>();
for (const [key, value] of Object.entries(obj)) {
if (allowNestedKey && key === NESTED_KEY) continue; // handled separately
// `Object.hasOwn`, not a truthiness check: a plain-object lookup like
// `KEY_SPECS["__proto__"]` returns an inherited member (Object.prototype,
// truthy) and would slip past `if (!spec)`, hitting the wrong error branch
// instead of the documented "Unknown key" message (#1996 tri-review P3).
if (!Object.hasOwn(KEY_SPECS, key)) {
throw new GitNexusRcError(
`Unknown key "${key}" in ${GITNEXUS_RC_FILENAME}. ${ALLOWED_KEYS_HINT}`,
);
}
const spec = KEY_SPECS[key];
const prev = setBy.get(spec.target);
if (prev && prev !== key) {
throw new GitNexusRcError(
`${GITNEXUS_RC_FILENAME}: "${prev}" and "${key}" both configure the same option; set only one.`,
);
}
setBy.set(spec.target, key);
(out as Record<string, unknown>)[spec.target] = normalizeValue(spec.kind, value, key);
}
return out;
};
/**
* Locate, read, parse, validate, and normalize `.gitnexusrc` at `repoRoot`.
*
* @returns the normalized config defaults, or `undefined` when no file exists
* (the normal case). Throws {@link GitNexusRcError} on any problem.
*/
export function loadAnalyzeConfig(repoRoot: string): Partial<AnalyzeOptions> | undefined {
const filePath = path.join(repoRoot, GITNEXUS_RC_FILENAME);View on GitHub (pinned to ac9a4e9abd)