{"record":{"id":"ba2ac6f206bc635b","repo":"nanocoai/nanoclaw","slug":"stdin-json-key-key-is-also-supplied-on-argv-ba2ac6","errorCode":null,"errorMessage":"--stdin-json key \"${key}\" is also supplied on argv","messagePattern":"--stdin-json key \"(.+?)\" is also supplied on argv","errorType":"validation","errorClass":"StdinJsonInputError","httpStatus":null,"severity":"error","filePath":"src/cli/stdin-json.ts","lineNumber":116,"sourceCode":" */\nfunction assertNoKeyConflicts(\n  stdinArgs: Readonly<Record<string, unknown>>,\n  argvArgs: Readonly<Record<string, unknown>>,\n): void {\n  const argvKeysByCanonical = new Map<string, string>();\n  for (const key of Object.keys(argvArgs)) {\n    const canonical = canonicalArgKey(key);\n    if (!argvKeysByCanonical.has(canonical)) argvKeysByCanonical.set(canonical, key);\n  }\n\n  const stdinKeysByCanonical = new Map<string, string>();\n  for (const key of Object.keys(stdinArgs)) {\n    if (key === '__proto__') {\n      throw new StdinJsonInputError('--stdin-json key \"__proto__\" is not allowed');\n    }\n\n    if (Object.prototype.hasOwnProperty.call(argvArgs, key)) {\n      throw new StdinJsonInputError(`--stdin-json key \"${key}\" is also supplied on argv`);\n    }\n\n    const canonical = canonicalArgKey(key);\n    const argvKey = argvKeysByCanonical.get(canonical);\n    if (argvKey !== undefined) {\n      throw new StdinJsonInputError(\n        `--stdin-json key \"${key}\" conflicts with argv key \"${argvKey}\" after CLI key normalization`,\n      );\n    }\n\n    const priorStdinKey = stdinKeysByCanonical.get(canonical);\n    if (priorStdinKey !== undefined) {\n      throw new StdinJsonInputError(\n        `--stdin-json keys \"${priorStdinKey}\" and \"${key}\" conflict after CLI key normalization`,\n      );\n    }\n    stdinKeysByCanonical.set(canonical, key);\n  }","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/cli/stdin-json.ts#L98-L134","documentation":"A key present in --stdin-json is also present as a direct argv flag; to avoid ambiguity about which value wins, the CLI rejects exact duplicates.","triggerScenarios":"`ncl groups update --id g1 --name a --stdin-json` where stdin JSON also contains \"name\" (or \"id\").","commonSituations":"Partial migration to --stdin-json where some flags were left on the command line.","solutions":["Remove the duplicate: keep each key either in argv or in stdin JSON, not both"],"exampleFix":"# before\nncl groups update --id g1 --name a --stdin-json < patch.json  # patch.json has \"name\"\n# after\nncl groups update --id g1 --stdin-json < patch.json           # patch.json has \"name\"","handlingStrategy":"validation","validationCode":"for (const k of Object.keys(stdin)) {\n  if (Object.hasOwn(argv, k)) throw new Error(`duplicate key: ${k}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Migrate flags into stdin JSON wholesale, don't split one option across both"],"tags":["cli","stdin-json","argument-conflict"],"backgroundTag":"conflicting-arguments","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}