{"record":{"id":"9e952d4cd2385475","repo":"jackwener/OpenCLI","slug":"approve-kinds-must-contain-at-least-one-approval","errorCode":null,"errorMessage":"--approve-kinds must contain at least one approval kind","messagePattern":"--approve-kinds must contain at least one approval kind","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/trae-cn/utils.js","lineNumber":87,"sourceCode":"export 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\nexport function ensurePrompt(text) {\n  const prompt = typeof text === 'string' ? text : '';\n  if (!prompt.trim()) {\n    throw new ArgumentError('text must not be empty');\n  }\n  return prompt;","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/trae-cn/utils.js#L69-L105","documentation":"After expanding items (where 'all' expands to terminal/delete/keep) and de-duplicating, normalizeApprovalKinds requires at least one approval kind. An empty result means nothing to approve was specified, so the library throws this ArgumentError rather than silently running with no approvals.","triggerScenarios":"Calling kinds/approvalKinds with --approve-kinds '' or a value that yields an empty list after trimming/expansion.","commonSituations":"Empty string passed through shell quoting, or config files where the kinds key is present but blank.","solutions":["Pass at least one kind, e.g. --approve-kinds terminal","Use --approve-kinds all to approve everything","Remove the empty flag so the library default applies if one exists"],"exampleFix":"// before\n--approve-kinds \"\"\n// after\n--approve-kinds all","handlingStrategy":"validation","validationCode":"const items = (approveKinds ?? '').split(',').map(s => s.trim()).filter(Boolean);\nif (items.length === 0) throw new Error('--approve-kinds requires at least one of terminal, delete, keep, or all');","typeGuard":"const hasApprovalKinds = (v) => typeof v === 'string' && v.split(',').map(s=>s.trim()).filter(Boolean).length > 0;","tryCatchPattern":"try { kinds = normalizeApprovalKinds(raw); } catch (e) { if (/at least one approval kind/.test(e.message)) { kinds = ['terminal']; console.warn('Empty --approve-kinds, defaulting to terminal'); } else throw e; }","preventionTips":["Never pass empty strings for list-style flags","Default to 'all' or a sane kind in wrapper scripts","Trim and filter list inputs before passing them through"],"tags":["cli","argument-validation","empty-input"],"backgroundTag":"invalid-cli-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}