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

  1. Add at least one valid agent entry (name, model/role, and its required fields per validatePodAgent)
  2. If a role-based filter emptied the list, widen the filter or provide a default agent
  3. 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

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


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/3b521dde78e0f409. Report an issue: GitHub.