{"record":{"id":"6fb30b50d5bf49fe","repo":"jackwener/OpenCLI","slug":"approve-kinds-must-contain-only-terminal-delete","errorCode":null,"errorMessage":"--approve-kinds must contain only terminal, delete, keep, or all","messagePattern":"--approve-kinds must contain only terminal, delete, keep, or all","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/trae-cn/utils.js","lineNumber":81,"sourceCode":"  if (!Number.isInteger(interval) || interval < 1 || interval > 300) {\n    throw new ArgumentError('--interval must be an integer between 1 and 300 seconds');\n  }\n  return interval;\n}\n\nexport function normalizeApprovalKinds(value, fallback = TRAE_CN_APPROVAL_DEFAULT_KINDS.join(',')) {\n  const raw = value === undefined || value === null || value === '' ? fallback : value;\n  const parts = Array.isArray(raw) ? raw : String(raw).split(',');\n  const expanded = [];\n  for (const part of parts) {\n    const item = String(part || '').trim().toLowerCase();\n    if (!item) continue;\n    if (item === 'all') {\n      expanded.push('terminal', 'delete', 'keep');\n      continue;\n    }\n    if (!['terminal', 'delete', 'keep'].includes(item)) {\n      throw new ArgumentError('--approve-kinds must contain only terminal, delete, keep, or all');\n    }\n    expanded.push(item);\n  }\n  const unique = Array.from(new Set(expanded));\n  if (unique.length === 0) {\n    throw new ArgumentError('--approve-kinds must contain at least one approval kind');\n  }\n  return unique;\n}\n\nexport function normalizeApprovalLimit(value, fallback = 1) {\n  const limit = value === undefined || value === null ? fallback : Number(value);\n  if (!Number.isInteger(limit) || limit < 1 || limit > 20) {\n    throw new ArgumentError('--limit must be an integer between 1 and 20');\n  }\n  return limit;\n}\n","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/trae-cn/utils.js#L63-L99","documentation":"normalizeApprovalKinds parses the --approve-kinds option and accepts only 'terminal', 'delete', 'keep', or 'all'. The library throws this ArgumentError immediately when any list item falls outside that whitelist, before any automation runs, so bad CLI input fails fast.","triggerScenarios":"Calling kinds/approvalKinds with --approve-kinds containing a misspelled or unsupported kind, e.g. 'termnal', 'bash', 'file-edit', or 'terminal,delete,exec'.","commonSituations":"Users copying --approve-kinds flags from a different tool's docs (e.g. Trae international vs Trae CN variants), or guessing kind names instead of using 'all'.","solutions":["Replace the invalid kind with one of terminal, delete, keep","Use 'all' to approve every supported kind at once","Check the exact spelling, kinds are lowercase and singular"],"exampleFix":"// before\n--approve-kinds terminal,exec\n// after\n--approve-kinds terminal,delete,keep","handlingStrategy":"validation","validationCode":"const KINDS = ['terminal','delete','keep'];\nconst items = approveKinds.split(',').map(s => s.trim()).filter(Boolean);\nconst valid = items.every(i => i === 'all' || KINDS.includes(i));\nif (!valid) throw new Error(`--approve-kinds must be one of ${[...KINDS,'all'].join(', ')}`);","typeGuard":"const isApprovalKind = (v) => ['terminal','delete','keep','all'].includes(v);","tryCatchPattern":"try { kinds = normalizeApprovalKinds(raw); } catch (e) { if (e instanceof ArgumentError) { console.error(e.message + ' (use: terminal, delete, keep, all)'); process.exitCode = 2; } else throw e; }","preventionTips":["Always validate flag values against the whitelist before invoking","Prefer 'all' when you want everything","Keep kind names in a shared constant to avoid typos"],"tags":["cli","argument-validation","input-whitelist"],"backgroundTag":"invalid-cli-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}