{"record":{"id":"2a55af11b05b5767","repo":"Yeachan-Heo/oh-my-codex","slug":"questions-must-be-a-non-empty-array","errorCode":null,"errorMessage":"questions must be a non-empty array","messagePattern":"questions must be a non-empty array","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/question/types.ts","lineNumber":198,"sourceCode":"  return normalizeQuestionItem({ ...raw, id: safeString(raw.id).trim() || 'q-1', header }, 0, header);\n}\n\nexport function normalizeQuestionInput(raw: unknown): QuestionInput {\n  if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n    throw new Error('question input must be a JSON object');\n  }\n\n  const input = raw as Record<string, unknown>;\n  const header = safeString(input.header).trim() || undefined;\n  const source = safeString(input.source).trim() || undefined;\n  const session_id = safeString(input.session_id).trim() || undefined;\n  const rawQuestions = Array.isArray(input.questions) ? input.questions : undefined;\n\n  const questions = rawQuestions\n    ? rawQuestions.map((item, index) => normalizeQuestionItem(item, index, header))\n    : [normalizeLegacyQuestion(input, header)];\n\n  if (questions.length === 0) throw new Error('questions must be a non-empty array');\n  const seenIds = new Set<string>();\n  for (const question of questions) {\n    if (seenIds.has(question.id)) throw new Error(`questions id must be unique: ${question.id}`);\n    seenIds.add(question.id);\n  }\n\n  const first = questions[0]!;\n  return {\n    ...(header ? { header } : {}),\n    question: first.question,\n    options: first.options,\n    allow_other: first.allow_other,\n    other_label: first.other_label,\n    multi_select: first.multi_select,\n    type: first.type,\n    questions,\n    ...(source ? { source } : {}),\n    ...(session_id ? { session_id } : {}),","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/question/types.ts#L180-L216","documentation":"After normalization the questions list must contain at least one question. Thrown when the input provides an explicit questions array that is empty (a legacy single-question object always yields one entry, so this only fires for explicit empty arrays).","triggerScenarios":"Calling normalizeQuestionInput with { questions: [] }.","commonSituations":"Programmatically filtering a questions array down to zero items before submission; template rendering that drops all questions conditionally.","solutions":["Ensure at least one question object is present in the questions array","Guard upstream: skip calling the API when the filtered list is empty instead of passing an empty array"],"exampleFix":"// before\nnormalizeQuestionInput({ questions: [] });\n// after\nif (questions.length === 0) throw new Error('no questions to ask');\nnormalizeQuestionInput({ questions });","handlingStrategy":"validation","validationCode":"if (Array.isArray(input.questions) && input.questions.length === 0) throw new Error('questions array is empty');","typeGuard":"const hasQuestions = (i: any) => !Array.isArray(i?.questions) || i.questions.length > 0;","tryCatchPattern":null,"preventionTips":["Skip API call when filtering leaves zero questions","Assert non-empty questions in test fixtures"],"tags":["input-validation","empty-array","question-schema"],"backgroundTag":"empty-collection-validation","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}