{"record":{"id":"53e715d4797a42d1","repo":"nanocoai/nanoclaw","slug":"stdin-json-key-key-conflicts-with-argv-key-53e715","errorCode":null,"errorMessage":"--stdin-json key \"${key}\" conflicts with argv key \"${argvKey}\" after CLI key normalization","messagePattern":"--stdin-json key \"(.+?)\" conflicts with argv key \"(.+?)\" after CLI key normalization","errorType":"validation","errorClass":"StdinJsonInputError","httpStatus":null,"severity":"error","filePath":"src/cli/stdin-json.ts","lineNumber":122,"sourceCode":"  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  }\n}\n","sourceCodeStart":104,"sourceCodeEnd":136,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/cli/stdin-json.ts#L104-L136","documentation":"After CLI key normalization (the canonicalization crud.ts parsers apply, e.g. dashes/underscores or alias collapsing), a stdin key maps to the same canonical form as an argv key, so they would silently override each other.","triggerScenarios":"`--agent-group x` on argv plus {\"agent_group\": ...} in stdin JSON — same canonical key, different spelling.","commonSituations":"Mixing snake_case JSON keys with kebab-case flags for the same option.","solutions":["Pick one spelling and keep that option in only one of argv or stdin JSON"],"exampleFix":"# before\nncl wirings create --agent-group a1 --stdin-json <<< '{\"agent_group\": \"a2\"}'\n# after\nncl wirings create --stdin-json <<< '{\"agent_group\": \"a2\"}'","handlingStrategy":"validation","validationCode":"const canon = (k: string) => k.replace(/-/g,'_');\nif (argvCanon.has(canon(stdinKey))) throw new Error('normalized conflict');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use one key style (snake_case in JSON, kebab-case on flags) and never both"],"tags":["cli","stdin-json","argument-conflict","normalization"],"backgroundTag":"conflicting-arguments","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}