{"record":{"id":"e81f9e95427a9e73","repo":"nanocoai/nanoclaw","slug":"unknown-flag-key-replace-g","errorCode":null,"errorMessage":"unknown flag --${key.replace(/_/g, '-')}","messagePattern":"unknown flag --(.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/crud.ts","lineNumber":404,"sourceCode":"\n/**\n * Validate `args` (already underscore-normalized) against a ColumnDef list:\n * unknown-flag rejection, required, enum, and type coercion per the declared\n * type. Returns a coerced copy; throws with a focused message on the first\n * problem. Works from any ColumnDef list so generic CRUD resources can opt\n * into the same strictness later without a second validator.\n */\nexport function validateArgs(\n  defs: ColumnDef[],\n  args: Record<string, unknown>,\n  opts: { allowExtra?: readonly string[] } = {},\n): Record<string, unknown> {\n  const declared = new Map(defs.map((d) => [d.name, d]));\n  const allowed = new Set<string>([...declared.keys(), ...(opts.allowExtra ?? DISPATCH_INJECTED_KEYS)]);\n\n  for (const key of Object.keys(args)) {\n    if (!allowed.has(key)) {\n      throw new Error(`unknown flag --${key.replace(/_/g, '-')}`);\n    }\n  }\n\n  const out: Record<string, unknown> = { ...args };\n  for (const def of defs) {\n    const flag = `--${def.name.replace(/_/g, '-')}`;\n    const v = args[def.name];\n    if (v === undefined) {\n      if (def.required) throw new Error(`${flag} is required`);\n      if (def.default !== undefined) out[def.name] = def.default;\n      continue;\n    }\n    // The client parses a value-less `--flag` as boolean true.\n    if (v === true && def.type !== 'boolean') {\n      throw new Error(`${flag} requires a value`);\n    }\n    switch (def.type) {\n      case 'number': {","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/cli/crud.ts#L386-L422","documentation":"validateArgs runs in strict mode for custom verbs that declare `args` (a ColumnDef list). After hyphens are normalized to underscores, every key in the parsed args must be either a declared flag or one of the dispatcher-injected keys (`id`, `agent_group_id`, `group`). Any other key is rejected as `unknown flag --<key>` so typos surface immediately instead of being silently ignored.","triggerScenarios":"Passing a flag a custom verb doesn't declare, e.g. `ncl tasks create --priority high` when the verb's args omit `priority`; misspelling a declared flag (`--mesage`); passing flags belonging to a different verb; or a verb that declares no `args` receiving any flag at all is fine, but one WITH declared args rejects everything undeclared.","commonSituations":"Assuming a generic verb accepts the same flags as another resource's verb; version drift where a flag was renamed or removed upstream; agents guessing flag names without reading the usage block.","solutions":["Run `ncl <resource> help` or read the usage block appended to the error to see the exact accepted flags","Fix the misspelling or remove the extraneous flag","If writing a custom operation, declare the flag in the verb's `args: ColumnDef[]` list"],"exampleFix":"# before\nncl groups restart --id g1 --rebild\n# Error: unknown flag --rebild\n\n# after\nncl groups restart --id g1 --rebuild","handlingStrategy":"validation","validationCode":"const allowed = new Set([...declaredFlagNames, 'id', 'agent_group_id', 'group']);\nconst extra = Object.keys(args).filter((k) => !allowed.has(k));\nif (extra.length) throw new Error(`not accepted: ${extra.join(', ')}`);","typeGuard":"function hasOnlyAllowedKeys(args: Record<string, unknown>, allowed: readonly string[]): boolean {\n  return Object.keys(args).every((k) => allowed.includes(k));\n}","tryCatchPattern":"catch (e) { if (e instanceof Error && e.message.startsWith('unknown flag')) { /* surface allowed list from help */ } else throw e; }","preventionTips":["Run `ncl <resource> help` before scripting an unfamiliar verb","Fetch flag names from the usage block, not memory"],"tags":["cli","argument-validation","unknown-flag","strict-mode"],"backgroundTag":"unknown-command-option","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}