{"record":{"id":"42567196f2fa50b8","repo":"nanocoai/nanoclaw","slug":"column-name-replace-g-must-be-true-o","errorCode":null,"errorMessage":"--${column.name.replace(/_/g, '-')} must be true or false","messagePattern":"--(.+?) must be true or false","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/crud.ts","lineNumber":178,"sourceCode":"// ---------------------------------------------------------------------------\n// Generic SQL handlers\n// ---------------------------------------------------------------------------\n\nfunction visibleColumns(def: ResourceDef): string[] {\n  return def.columns.map((c) => c.name);\n}\n\nfunction coerceListFilter(column: ColumnDef, value: unknown): unknown {\n  switch (column.type) {\n    case 'number': {\n      const number = Number(value);\n      if (Number.isNaN(number)) throw new Error(`--${column.name.replace(/_/g, '-')} must be a number`);\n      return number;\n    }\n    case 'boolean':\n      if (value === true || value === 'true' || value === '1' || value === 1) return 1;\n      if (value === false || value === 'false' || value === '0' || value === 0) return 0;\n      throw new Error(`--${column.name.replace(/_/g, '-')} must be true or false`);\n    case 'json':\n      return typeof value === 'string' ? value : JSON.stringify(value);\n    case 'string':\n      return String(value);\n  }\n}\n\nfunction listOrder(def: ResourceDef): string {\n  if (def.listOrder) return def.listOrder;\n  const timestamp = def.columns.find((column) => column.name.endsWith('_at'))?.name;\n  return timestamp ? `${timestamp} DESC, ${def.idColumn}` : def.idColumn;\n}\n\nfunction genericList(def: ResourceDef) {\n  const cols = visibleColumns(def).join(', ');\n  const filterableColumns = new Map(def.columns.filter((c) => !c.generated).map((c) => [c.name, c]));\n  return async (args: Record<string, unknown>) => {\n    const limit = args.limit !== undefined ? Math.max(1, Number(args.limit)) : 200;","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/cli/crud.ts#L160-L196","documentation":"Thrown by coerceListFilter in src/cli/crud.ts when a boolean column filter receives a value that is not one of true/false/'true'/'false'/'1'/'0'/1/0. The generic list handler coerces CLI filter flags into SQLite-storable 0/1 integers, and any other string (e.g. 'yes', 'on') is rejected. This protects boolean columns from being compared against non-boolean text.","triggerScenarios":"Running `ncl <resource> list --<boolean-column> yes` or `--<boolean-column> on/off`, or any list filter where the resource defines a boolean column (e.g. is_default, enabled) and the caller passes an unrecognized truthiness spelling.","commonSituations":"Scripts assuming 'yes'/'no' or 'on'/'off' work as booleans; passing an empty string; passing 'True' with a capital T.","solutions":["Use exactly true or false (also accepted: 1/0, 'true'/'false')","Check the column definition in src/cli/resources/<resource>.ts to confirm the column is actually boolean","Quote the value in shells that mangle bare true/false"],"exampleFix":"# before\nncl groups list --is-default yes\n# after\nncl groups list --is-default true","handlingStrategy":"validation","validationCode":"const BOOL_OK = new Set(['true','false','1','0',true,false,1,0]);\nfunction assertBoolFlag(name: string, v: unknown) {\n  if (!BOOL_OK.has(v as any)) throw new Error(`${name} must be true or false`);\n}","typeGuard":"function isBoolFilter(v: unknown): boolean {\n  return [true,false,'true','false','1','0',1,0].includes(v as any);\n}","tryCatchPattern":null,"preventionTips":["Normalize boolean CLI inputs to true/false before calling ncl","Document accepted boolean spellings in wrapper scripts"],"tags":["cli","validation","boolean"],"backgroundTag":"cli-argument-validation","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}