ruvnet/ruflo · error · PodTemplateValidationError
agents must have ≥1 entry
Error message
agents must have ≥1 entry
What it means
After requireArray() parses the top-level agents array (each entry already validated by validatePodAgent), validatePodTemplate() rejects an empty list. A pod is defined by its agents; zero agents means nothing can execute, so the schema requires at least one valid agent entry.
Source
Thrown at v3/@claude-flow/cli/src/business-pods/pod-schema.ts:205
export function validatePodTemplate(json: unknown): PodTemplate {
if (!isObject(json)) {
throw new PodTemplateValidationError('pod-template must be a JSON object', '/');
}
const name = requireString(json, 'name', '/');
if (!/^[a-z][a-z0-9-]*$/.test(name)) {
throw new PodTemplateValidationError('name must be lowercase-kebab (e.g. "sales")', '/');
}
const displayName = requireString(json, 'displayName', '/');
const roomId = requireString(json, 'roomId', '/');
if (!/^[A-Za-z0-9_.\-:/@#]+$/.test(roomId)) {
throw new PodTemplateValidationError(
'roomId may only contain [A-Za-z0-9_.\\-:/@#]',
'/',
);
}
const agents = requireArray(json, 'agents', '/', validatePodAgent);
if (agents.length === 0) {
throw new PodTemplateValidationError('agents must have ≥1 entry', '/');
}
const allowedMcpTools = requireArray(json, 'allowedMcpTools', '/', (t, tp) => {
if (typeof t !== 'string' || t.length === 0) {
throw new PodTemplateValidationError(
'allowedMcpTools entries must be non-empty strings',
tp,
);
}
return t;
});
if (allowedMcpTools.length === 0) {
throw new PodTemplateValidationError('allowedMcpTools must have ≥1 entry', '/');
}
const bench = validatePodBench(json.bench, '/bench');
const piiPolicy = requireString(json, 'piiPolicy', '/');
if (!PII_POLICIES.includes(piiPolicy as PiiPolicy)) {
throw new PodTemplateValidationError(
`piiPolicy must be one of: ${PII_POLICIES.join(', ')}`,View on GitHub (pinned to fa13ee4ad6)
Solutions
- Add at least one valid agent entry (name, model/role, and its required fields per validatePodAgent)
- If a role-based filter emptied the list, widen the filter or provide a default agent
- Treat 'no agents' as a build error in your template pipeline rather than shipping it
Example fix
// before
"agents": []
// after
"agents": [{ "name": "lead", "role": "coordinator" }] Defensive patterns
Strategy: try-catch
Validate before calling
if (!Array.isArray(json.agents) || json.agents.length === 0) {
throw new Error('template must define at least one agent');
} Type guard
function hasAtLeastOneAgent(v: unknown): boolean {
return Array.isArray((v as { agents?: unknown[] })?.agents) && ((v as { agents: unknown[] }).agents.length > 0);
} Try / catch
try { validatePodTemplate(json); } catch (err) {
if (err instanceof PodTemplateValidationError && err.message === 'agents must have ≥1 entry') {
// roster filter emptied the list — add a default agent and re-validate
}
} Prevention
- Fail template generation early when an environment filter yields zero agents
- Seed new templates from a known-good example containing one agent
When it happens
Trigger: A template with "agents": []. Each individual malformed agent would have thrown earlier from validatePodAgent, so reaching this error means every entry validated but the list is empty.
Common situations: Roster-driven template generators that filter agents by environment and end up with none; scaffolding templates shipped with an empty placeholder array; conditional agent inclusion logic that removes all agents in a staging config.
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.scheduleHours must be ≥1
- auditReadView must be an object
- includedEventTypes entries must be non-empty strings
- auditReadView.retentionDays must be ≥1
- roomId may only contain [A-Za-z0-9_.\-:/@#]
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/3b521dde78e0f409.
Report an issue: GitHub.