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
- Set bench.scheduleHours to an integer >= 1 (e.g. 24 for daily bench runs)
- If you need sub-hour bench scheduling, encode it in the top-level cronSchedule field instead
- 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
- Author templates in TypeScript with the PodTemplate type so the compiler catches bad cadence values
- Add a CI schema check that runs validatePodTemplate on every template file
- Keep a worked example template as the starting point for new pods
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
- auditReadView must be an object
- includedEventTypes entries must be non-empty strings
- auditReadView.retentionDays must be ≥1
- pod-template must be a JSON object
- name must be lowercase-kebab (e.g. "sales")
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/200a81d97ccf8c14.
Report an issue: GitHub.