ruvnet/ruflo · error · PodTemplateValidationError
agent must be an object
Error message
agent must be an object
What it means
Thrown by validatePodAgent() when an entry of the template's agents[] array is not a plain object (isObject excludes null and arrays). Each agent entry must be an object with role, agentType, description (non-empty strings) and preferLocal (boolean).
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 fa13ee4ad6)
Solutions
- Expand each agent entry into the full object shape: {"role":"...","agentType":"researcher","description":"...","preferLocal":true}
- The error's path pinpoints which index (e.g. /agents[2]) is malformed
- agentType must be a known ruflo agent type (researcher/coder/...)
- Lint templates with validatePodTemplate before shipping
Example fix
// before
"agents": ["researcher", "coder"]
// after
"agents": [
{ "role": "scout", "agentType": "researcher", "description": "Finds leads", "preferLocal": true },
{ "role": "builder", "agentType": "coder", "description": "Writes outreach", "preferLocal": false }
] Defensive patterns
Strategy: type-guard
Validate before calling
function isPodAgentLike(v: unknown): boolean {
return typeof v === 'object' && v !== null && !Array.isArray(v);
}
const badIdx = (template.agents as unknown[]).findIndex((a) => !isPodAgentLike(a));
if (badIdx >= 0) fail(`agents[${badIdx}] must be an object with role/agentType/description/preferLocal`); Type guard
function isPodAgentShape(v: unknown): v is { role: string; agentType: string; description: string; preferLocal: boolean } {
if (typeof v !== 'object' || v === null || Array.isArray(v)) return false;
const o = v as Record<string, unknown>;
return typeof o.role === 'string' && o.role.length > 0 &&
typeof o.agentType === 'string' && o.agentType.length > 0 &&
typeof o.description === 'string' && o.description.length > 0 &&
typeof o.preferLocal === 'boolean';
} Try / catch
try {
validatePodTemplate(template);
} catch (e) {
if (e instanceof PodTemplateValidationError && e.message.includes('agent must be an object')) {
fail(`Expand the shorthand at ${e.path} into a full agent object`);
} else throw e;
} Prevention
- Ban bare-string agents (["researcher"]) in template reviews
- If authoring in YAML, define agents: as a list of mappings, not scalars
- Re-use the isPodAgentShape guard in template generators
When it happens
Trigger: validatePodTemplate() where agents contains a bare string ("researcher"), null, a number, or a nested array instead of an object like {"role":"scout","agentType":"researcher","description":"...","preferLocal":true}.
Common situations: Shorthand agents: ["researcher","coder"] written for brevity; a JSON merge that dropped an object to null; copying examples from docs that abbreviated the structure.
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
- field "${key}" must be a non-empty string
- field "${key}" must be a finite number
- field "${key}" must be a boolean
- field "${key}" must be an array
- bench must be an object
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/f729ebbff37e333d.
Report an issue: GitHub.