ruvnet/ruflo · error · PodTemplateValidationError

bench must be an object

Error message

bench must be an object

What it means

Thrown by validatePodBench() when the template's bench field is not a plain object. bench must contain name, description (non-empty strings), successCriteria (non-empty array of non-empty strings), and scheduleHours (number ≥1) — but this specific error means the container itself was wrong before field checks ran.

Source

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

  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;
  });
  if (successCriteria.length === 0) {
    throw new PodTemplateValidationError('bench.successCriteria must have ≥1 entry', path);
  }
  const scheduleHours = requireNumber(item, 'scheduleHours', path);
  if (scheduleHours < 1) {
    throw new PodTemplateValidationError('bench.scheduleHours must be ≥1', path);
  }
  return { name, description, successCriteria, scheduleHours };
}

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Add a full bench object: {"name":"sales-bench","description":"...","successCriteria":["..."],"scheduleHours":24}
  2. Remember bench is required — there is no 'no bench' pod
  3. Use the error path (it points at /bench) to locate the slot in your JSON
  4. Validate in CI so missing bench sections never reach runtime

Example fix

// before
{ "bench": null }
// after
"bench": { "name": "sales-pipeline-bench", "description": "Weekly pipeline health", "successCriteria": ["≥10 qualified leads"], "scheduleHours": 168 }
Defensive patterns

Strategy: type-guard

Validate before calling

const bench = template.bench as unknown;
if (typeof bench !== 'object' || bench === null || Array.isArray(bench)) {
  fail('bench is required and must be an object: {name, description, successCriteria[], scheduleHours}');
}

Type guard

function isPodBenchShape(v: unknown): v is { name: string; description: string; successCriteria: string[]; scheduleHours: number } {
  if (typeof v !== 'object' || v === null || Array.isArray(v)) return false;
  const o = v as Record<string, unknown>;
  return typeof o.name === 'string' && typeof o.description === 'string' &&
    Array.isArray(o.successCriteria) && typeof o.scheduleHours === 'number';
}

Try / catch

try {
  validatePodTemplate(template);
} catch (e) {
  if (e instanceof PodTemplateValidationError && e.message.includes('bench must be an object')) {
    fail('Every pod requires a bench section — it drives Darwin /loop scoring');
  } else throw e;
}

Prevention

When it happens

Trigger: validatePodTemplate() with "bench": null, "bench": "weekly-check", bench missing entirely (undefined fails isObject), or bench as an array.

Common situations: Template authored without a bench section (it is mandatory, every pod needs Darwin /loop scoring); bench reduced to a string name for brevity; optional-looking field omitted because similar configs mark it optional.

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/70a96702a42d46ea. Report an issue: GitHub.