ruvnet/ruflo · error · PodTemplateValidationError

pod-template at ${path}: agent must be an object

Error message

pod-template at ${path}: agent must be an object

What it means

Thrown by validatePodAgent() when an element inside the agents array is not a plain object (null, an array, a string, a number, etc.). Each agent entry must be an object with role, agentType, description, and preferLocal fields. The isObject() helper excludes null and arrays, so only genuine plain objects pass.

Source

Thrown at v3/@claude-flow/cli/src/business-pods/pod-schema.ts:127

function requireBoolean(parent: Record<string, unknown>, key: string, path: string): boolean {
  const v = parent[key];
  if (typeof v !== 'boolean') {
    throw new PodTemplateValidationError(`field "${key}" must be a boolean`, path);
  }
  return v;
}

function requireArray<T>(parent: Record<string, unknown>, key: string, path: string,
                          itemValidator: (item: unknown, ipath: string) => T): T[] {
  const v = parent[key];
  if (!Array.isArray(v)) {
    throw new PodTemplateValidationError(`field "${key}" must be an array`, path);
  }
  return v.map((item, idx) => itemValidator(item, `${path}/${key}[${idx}]`));
}

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;
  });

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Read the error path — it includes the array index (e.g., /agents[2]) pinpointing the bad entry
  2. Ensure every agents[] element is a full object with role, agentType, description, and preferLocal

Example fix

// before:
"agents": [ { "role": "lead", ... }, null ] // second entry is null, throws

// after:
"agents": [ { "role": "lead", ... }, { "role": "researcher", "agentType": "researcher", ... } ]
Defensive patterns

Strategy: validation

Validate before calling

import { validatePodTemplate, PodTemplateValidationError } from '@claude-flow/cli/business-pods/pod-schema';

try {
  const pod = validatePodTemplate(parsedJson);
} catch (e) {
  if (e instanceof PodTemplateValidationError) {
    // e.path includes the array index, e.g. /agents[2]
    console.error(`Agent entry error at ${e.path}: ${e.message}`);
  }
}

Try / catch

import { validatePodTemplate, PodTemplateValidationError } from '@claude-flow/cli/business-pods/pod-schema';

try {
  const pod = validatePodTemplate(raw);
} catch (e) {
  if (e instanceof PodTemplateValidationError) {
    console.error(e.message); // path includes /agents[idx]
    process.exit(1);
  }
  throw e;
}

Prevention

When it happens

Trigger: validatePodTemplate() iterates the agents array via requireArray() and one element is null, a primitive, or a nested array.

Common situations: A trailing comma in YAML producing a null entry; an agent entry that is a bare string ("lead-gen-agent"); a copy-paste error inserting an array where an object was expected.

Related errors


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