{"record":{"id":"5fb1c17ee6b5e5d2","repo":"ruvnet/ruflo","slug":"successcriteria-entries-must-be-non-empty-strings","errorCode":null,"errorMessage":"successCriteria entries must be non-empty strings","messagePattern":"successCriteria entries must be non-empty strings","errorType":"validation","errorClass":"PodTemplateValidationError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/business-pods/pod-schema.ts","lineNumber":142,"sourceCode":"}\n\nfunction validatePodAgent(item: unknown, path: string): PodAgent {\n  if (!isObject(item)) throw new PodTemplateValidationError('agent must be an object', path);\n  return {\n    role: requireString(item, 'role', path),\n    agentType: requireString(item, 'agentType', path),\n    description: requireString(item, 'description', path),\n    preferLocal: requireBoolean(item, 'preferLocal', path),\n  };\n}\n\nfunction validatePodBench(item: unknown, path: string): PodBench {\n  if (!isObject(item)) throw new PodTemplateValidationError('bench must be an object', path);\n  const name = requireString(item, 'name', path);\n  const description = requireString(item, 'description', path);\n  const successCriteria = requireArray(item, 'successCriteria', path, (s, sp) => {\n    if (typeof s !== 'string' || s.length === 0) {\n      throw new PodTemplateValidationError('successCriteria entries must be non-empty strings', sp);\n    }\n    return s;\n  });\n  if (successCriteria.length === 0) {\n    throw new PodTemplateValidationError('bench.successCriteria must have ≥1 entry', path);\n  }\n  const scheduleHours = requireNumber(item, 'scheduleHours', path);\n  if (scheduleHours < 1) {\n    throw new PodTemplateValidationError('bench.scheduleHours must be ≥1', path);\n  }\n  return { name, description, successCriteria, scheduleHours };\n}\n\nfunction validateAuditReadView(item: unknown, path: string): PodAuditReadView {\n  if (!isObject(item)) {\n    throw new PodTemplateValidationError('auditReadView must be an object', path);\n  }\n  const includedEventTypes = requireArray(item, 'includedEventTypes', path, (s, sp) => {","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/business-pods/pod-schema.ts#L124-L160","documentation":"Thrown inside validatePodBench()'s requireArray item validator when a bench.successCriteria entry is not a non-empty string — e.g. a number, null, object, or \"\". The error path includes the exact index (/bench/successCriteria[2]) so the offending bullet can be found.","triggerScenarios":"validatePodTemplate() with successCriteria like [\"demo booked\", 5, \"\"] — the numeric score or empty string entry fails while the array itself is valid.","commonSituations":"Mixing metrics into criteria lists (\"criteria\": [\"leads\", 10]); templating engines injecting null for blank bullets; copy-paste leaving an empty string placeholder.","solutions":["Make every entry a non-empty string: spell numbers out (\"≥10 qualified leads\") instead of bare 5","Remove empty-string placeholder bullets","Use the indexed path in the error to jump straight to the bad entry","Pre-validate generated templates with validatePodTemplate"],"exampleFix":"// before\n\"successCriteria\": [\"demo booked\", 10, \"\"]\n// after\n\"successCriteria\": [\"demo booked\", \"≥10 qualified leads per week\"]","handlingStrategy":"validation","validationCode":"const criteria = (template.bench as { successCriteria?: unknown[] }).successCriteria ?? [];\nconst badIdx = criteria.findIndex((c) => typeof c !== 'string' || c.length === 0);\nif (badIdx >= 0) fail(`successCriteria[${badIdx}] must be a non-empty string`);","typeGuard":"function isNonEmptyString(v: unknown): v is string {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  validatePodTemplate(template);\n} catch (e) {\n  if (e instanceof PodTemplateValidationError && e.message.includes('successCriteria entries must be non-empty strings')) {\n    fail(`Fix the entry at ${e.path} — spell out numbers, drop empty bullets`);\n  } else throw e;\n}","preventionTips":["Express numeric targets as strings: \"≥10 qualified leads\", not 10","Strip empty placeholder bullets before validating","Use the indexed JSON pointer in the error to jump to the exact entry"],"tags":["pod","schema","validation","json","bench","success-criteria"],"backgroundTag":"schema-validation-failed","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}