{"record":{"id":"53ee52c3fc356067","repo":"nanocoai/nanoclaw","slug":"col-name-must-be-one-of-col-enum-join","errorCode":null,"errorMessage":"${col.name} must be one of: ${col.enum.join(', ')}","messagePattern":"(.+?) must be one of: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/crud.ts","lineNumber":248,"sourceCode":"\n    // Pass 1: generated columns + explicit caller args only. Static defaults\n    // wait until after resolveDefaults so the hook sees exactly what the\n    // caller provided and a static default never pre-empts context-aware\n    // resolution.\n    for (const col of def.columns) {\n      if (col.generated) {\n        if (col.name === def.idColumn) {\n          values[col.name] = randomUUID();\n        } else if (col.name.endsWith('_at')) {\n          values[col.name] = new Date().toISOString();\n        }\n        continue;\n      }\n\n      const v = args[col.name];\n      if (v !== undefined) {\n        if (col.enum && !col.enum.includes(String(v))) {\n          throw new Error(`${col.name} must be one of: ${col.enum.join(', ')}`);\n        }\n        values[col.name] = col.type === 'number' ? Number(v) : v;\n      } else if (col.required) {\n        throw new Error(`--${col.name.replace(/_/g, '-')} is required`);\n      }\n    }\n\n    // Pass 2: context-aware defaults + cross-column validation.\n    if (def.resolveDefaults) def.resolveDefaults(values);\n\n    // Pass 3: static defaults for whatever is still unset.\n    for (const col of def.columns) {\n      if (col.generated || values[col.name] !== undefined) continue;\n      if (col.default !== undefined) {\n        values[col.name] = col.default;\n      } else if (col.defaultFrom !== undefined && values[col.defaultFrom] !== undefined) {\n        values[col.name] = values[col.defaultFrom];\n      }","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/cli/crud.ts#L230-L266","documentation":"Thrown by genericCreate in src/cli/crud.ts during pass-1 column validation when a create argument's value is not in the column's declared enum list. Resource definitions may restrict a column to a fixed set of allowed strings, and any value outside that set is rejected before the INSERT.","triggerScenarios":"`ncl <resource> create --<enum-column> <bad-value>` e.g. creating a wiring with an unknown session_mode or engage_mode not in the enum defined in src/cli/resources/.","commonSituations":"Version drift: a valid value in an older NanoClaw was removed/renamed; guessing enum values instead of checking `ncl <resource> help`.","solutions":["Read the error message — it lists every allowed value","Run `ncl <resource> help` to see the column's accepted values","If you expected the value to exist, update your checkout (values come from src/cli/resources/ definitions)"],"exampleFix":"# before\nncl wirings create --session-mode solo ...\n# after\nncl wirings create --session-mode shared ...   # use a listed value","handlingStrategy":"validation","validationCode":"const allowed = def.columns.find(c => c.name === col)!.enum;\nif (!allowed.includes(String(value))) throw new Error(`use one of ${allowed.join(', ')}`);","typeGuard":"const inEnum = (v: unknown, allowed: string[]) => allowed.includes(String(v));","tryCatchPattern":null,"preventionTips":["Fetch allowed values from `ncl <resource> help` before scripting creates","Pin enum spellings in one constants module"],"tags":["cli","enum","validation","crud"],"backgroundTag":"enum-value-invalid","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}