{"record":{"id":"fd7c384fa8d31858","repo":"nanocoai/nanoclaw","slug":"flag-is-required","errorCode":null,"errorMessage":"${flag} is required","messagePattern":"(.+?) is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/crud.ts","lineNumber":413,"sourceCode":"  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': {\n        const n = Number(v);\n        if (Number.isNaN(n)) throw new Error(`${flag} must be a number, got \"${v}\"`);\n        out[def.name] = n;\n        break;\n      }\n      case 'boolean': {\n        if (v === true || v === 'true' || v === '1') out[def.name] = true;\n        else if (v === false || v === 'false' || v === '0') out[def.name] = false;\n        else throw new Error(`${flag} must be true or false, got \"${v}\"`);","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/cli/crud.ts#L395-L431","documentation":"During strict validation of a custom verb, a ColumnDef marked `required: true` was absent from the parsed args (value undefined and no default). The verb cannot proceed without it, so validation fails before the handler runs.","triggerScenarios":"Omitting a required flag entirely, e.g. `ncl messaging-groups create` when `--name` is required; passing the flag with a different spelling so it lands as an unknown key (which first triggers the unknown-flag error); passing `--flag` value-less so it parses as boolean true rather than the expected typed value (that hits the requires-a-value error instead).","commonSituations":"Minimal invocations copied from docs that omit a newly-required flag after a version bump; agents truncating long commands; conditional shell logic that skips a flag.","solutions":["Read the usage block in the error message — it lists required flags with `<...>` markers","Re-run with the required flag: add `--<name> <value>`","For custom-operation authors: give the ColumnDef a `default` if the flag should be optional"],"exampleFix":"# before\nncl wirings create --agent-group-id g1\n# Error: --messaging-group-id is required\n\n# after\nncl wirings create --agent-group-id g1 --messaging-group-id m1","handlingStrategy":"validation","validationCode":"const missing = defs.filter((d) => d.required && args[d.name] === undefined);\nif (missing.length) throw new Error(`missing required: ${missing.map((d) => '--' + d.name).join(' ')}`);","typeGuard":null,"tryCatchPattern":"catch (e) { if (e instanceof Error && /is required$/.test(e.message)) { /* collect and prompt */ } else throw e; }","preventionTips":["Include every required flag shown in the usage block's `<...>` markers","Write wrapper functions with typed parameters so omissions are compile-time errors"],"tags":["cli","argument-validation","required-field"],"backgroundTag":"missing-required-argument","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}