ruvnet/ruflo · error · PodTemplateValidationError

pod-template at ${path}: agents must have ≥1 entry

Error message

pod-template at ${path}: agents must have ≥1 entry

What it means

Thrown by validatePodTemplate() when the 'agents' array is present and valid as an array but contains zero entries. Each pod must define at least one agent composition (PodAgent with role, agentType, description, preferLocal). An empty agents array means the pod has no execution capacity.

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 6b01dc5a68)

Solutions

  1. Add at least one agent object to the agents array with role, agentType, description, and preferLocal fields
  2. Verify the agentType is one of the values in KNOWN_AGENT_TYPES (e.g. 'coder', 'researcher', 'reviewer')

Example fix

// before
{ "agents": [] }

// after
{ "agents": [
  { "role": "lead-gen-agent", "agentType": "researcher", "description": "Finds leads", "preferLocal": true }
] }
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(template.agents) || template.agents.length === 0) {
  throw new Error('Pod must define at least one agent');
}

Type guard

function hasAgents(template: unknown): boolean {
  return typeof template === 'object' && template !== null &&
    Array.isArray((template as Record<string, unknown>).agents) &&
    ((template as Record<string, unknown>).agents as unknown[]).length > 0;
}

Try / catch

try {
  validatePodTemplate(json);
} catch (e) {
  if (e instanceof PodTemplateValidationError && e.message.includes('agents must have')) {
    // Add at least one agent entry
  }
}

Prevention

When it happens

Trigger: The pod-template JSON has "agents": [] — an empty array. The requireArray helper succeeds (it is a valid array), but the subsequent length check fails.

Common situations: An agent entry was deleted during editing and the array was left empty; a template was scaffolded with a placeholder empty agents array that was never filled in.

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/3f01174b7e9eb3ae. Report an issue: GitHub.