ruvnet/ruflo · error · PodTemplateValidationError

bench.scheduleHours must be ≥1

Error message

bench.scheduleHours must be ≥1

What it means

Thrown by validatePodBench() in the business-pod template schema. After requireNumber() confirms bench.scheduleHours is a number, the value must be at least 1 — the bench (automated evaluation) must be scheduled at a minimum cadence of once per hour. PodTemplateValidationError carries the JSON-pointer path (e.g. /bench/scheduleHours) so you can locate the offending field.

Source

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

  };
}

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

function validateAuditReadView(item: unknown, path: string): PodAuditReadView {
  if (!isObject(item)) {
    throw new PodTemplateValidationError('auditReadView must be an object', path);
  }
  const includedEventTypes = requireArray(item, 'includedEventTypes', path, (s, sp) => {
    if (typeof s !== 'string' || s.length === 0) {
      throw new PodTemplateValidationError('includedEventTypes entries must be non-empty strings', sp);
    }
    return s;
  });
  const retentionDays = requireNumber(item, 'retentionDays', path);
  if (retentionDays < 1) {
    throw new PodTemplateValidationError('auditReadView.retentionDays must be ≥1', path);
  }

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Set bench.scheduleHours to an integer >= 1 (e.g. 24 for daily bench runs)
  2. If you need sub-hour bench scheduling, encode it in the top-level cronSchedule field instead
  3. Re-validate with the business_pod_validate MCP tool and confirm the error path moves past /bench/scheduleHours

Example fix

// before
"bench": { "name": "weekly-review", "description": "...", "successCriteria": ["..."], "scheduleHours": 0 }
// after
"bench": { "name": "weekly-review", "description": "...", "successCriteria": ["..."], "scheduleHours": 168 }
Defensive patterns

Strategy: try-catch

Validate before calling

const t = JSON.parse(raw);
if (typeof t?.bench?.scheduleHours !== 'number' || t.bench.scheduleHours < 1) {
  throw new Error('fix bench.scheduleHours before validating');
}

Type guard

function hasValidScheduleHours(t: unknown): boolean {
  const b = (t as { bench?: { scheduleHours?: unknown } })?.bench;
  return typeof b?.scheduleHours === 'number' && (b.scheduleHours as number) >= 1;
}

Try / catch

import { validatePodTemplate, PodTemplateValidationError } from './pod-schema.js';
try {
  const pod = validatePodTemplate(json);
} catch (err) {
  if (err instanceof PodTemplateValidationError && /scheduleHours/.test(err.message)) {
    // err.path points at /bench/scheduleHours — surface to the template author
  }
  throw err;
}

Prevention

When it happens

Trigger: A pod template JSON passed to validatePodTemplate(), the business_pod_validate MCP tool, or pod-tick.mjs pre-flight where bench.scheduleHours is 0, negative, or a fraction below 1 (e.g. 0.5). requireNumber would already have rejected non-numbers with a different message, so this error means the value is numeric but < 1.

Common situations: Authors expressing cadence in minutes (scheduleHours: 30 for 'every 30 minutes'), porting configs where 0 meant 'disabled', or using 0.5 intending twice-per-hour. Sub-hour cadence belongs in cronSchedule, not scheduleHours.

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/200a81d97ccf8c14. Report an issue: GitHub.