ruvnet/ruflo · error · PodTemplateValidationError
successCriteria entries must be non-empty strings
Error message
successCriteria entries must be non-empty strings
What it means
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.
Source
Thrown at v3/@claude-flow/cli/src/business-pods/pod-schema.ts:142
}
function validatePodAgent(item: unknown, path: string): PodAgent {
if (!isObject(item)) throw new PodTemplateValidationError('agent must be an object', path);
return {
role: requireString(item, 'role', path),
agentType: requireString(item, 'agentType', path),
description: requireString(item, 'description', path),
preferLocal: requireBoolean(item, 'preferLocal', path),
};
}
function validatePodBench(item: unknown, path: string): PodBench {
if (!isObject(item)) throw new PodTemplateValidationError('bench must be an object', path);
const name = requireString(item, 'name', path);
const description = requireString(item, 'description', path);
const successCriteria = requireArray(item, 'successCriteria', path, (s, sp) => {
if (typeof s !== 'string' || s.length === 0) {
throw new PodTemplateValidationError('successCriteria entries must be non-empty strings', sp);
}
return s;
});
if (successCriteria.length === 0) {
throw new PodTemplateValidationError('bench.successCriteria must have ≥1 entry', path);
}
const scheduleHours = requireNumber(item, 'scheduleHours', path);
if (scheduleHours < 1) {
throw new PodTemplateValidationError('bench.scheduleHours must be ≥1', path);
}
return { name, description, successCriteria, scheduleHours };
}
function validateAuditReadView(item: unknown, path: string): PodAuditReadView {
if (!isObject(item)) {
throw new PodTemplateValidationError('auditReadView must be an object', path);
}
const includedEventTypes = requireArray(item, 'includedEventTypes', path, (s, sp) => {View on GitHub (pinned to fa13ee4ad6)
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
Example fix
// before "successCriteria": ["demo booked", 10, ""] // after "successCriteria": ["demo booked", "≥10 qualified leads per week"]
Defensive patterns
Strategy: validation
Validate before calling
const criteria = (template.bench as { successCriteria?: unknown[] }).successCriteria ?? [];
const badIdx = criteria.findIndex((c) => typeof c !== 'string' || c.length === 0);
if (badIdx >= 0) fail(`successCriteria[${badIdx}] must be a non-empty string`); Type guard
function isNonEmptyString(v: unknown): v is string {
return typeof v === 'string' && v.length > 0;
} Try / catch
try {
validatePodTemplate(template);
} catch (e) {
if (e instanceof PodTemplateValidationError && e.message.includes('successCriteria entries must be non-empty strings')) {
fail(`Fix the entry at ${e.path} — spell out numbers, drop empty bullets`);
} else throw e;
} Prevention
- 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
When it happens
Trigger: validatePodTemplate() with successCriteria like ["demo booked", 5, ""] — the numeric score or empty string entry fails while the array itself is valid.
Common situations: Mixing metrics into criteria lists ("criteria": ["leads", 10]); templating engines injecting null for blank bullets; copy-paste leaving an empty string placeholder.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- bench must be an object
- bench.successCriteria must have ≥1 entry
- field "${key}" must be a non-empty string
- field "${key}" must be a finite number
- field "${key}" must be a boolean
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/5fb1c17ee6b5e5d2.
Report an issue: GitHub.