ruvnet/ruflo · error · PodTemplateValidationError
auditReadView.retentionDays must be ≥1
Error message
auditReadView.retentionDays must be ≥1
What it means
Thrown by validateAuditReadView() after requireNumber() parses auditReadView.retentionDays: the value must be >= 1. Zero-day retention is treated as invalid configuration (it would mean the auditor sees nothing), so the schema forces an explicit positive retention window.
Source
Thrown at v3/@claude-flow/cli/src/business-pods/pod-schema.ts:168
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);
}
return { includedEventTypes, retentionDays };
}
// POSIX cron — five or six space-separated fields. Permissive on field
// contents (digits, *, -, /, ,) — actual cron evaluation happens at schedule
// time. We only catch obviously malformed values here.
const CRON_RE = /^([\d*/,\-]+\s+){4,5}[\d*/,\-]+$/;
/**
* Validate `json` and return a typed `PodTemplate`. Throws
* `PodTemplateValidationError` with a JSON-pointer-style path on failure.
*
* Used by:
* - `business_pod_validate` MCP tool — returns the error verbatim
* - `pod-tick.mjs` — pre-flight check before any pod execution
* - any external schema-loader that wants typed templates
*/View on GitHub (pinned to fa13ee4ad6)
Solutions
- Set retentionDays to the smallest acceptable positive integer (e.g. 1) if you want minimal retention
- If long retention was intended, use the explicit number of days (365, 2555, ...)
- Re-run business_pod_validate to confirm the template is now fully valid
Example fix
// before
"auditReadView": { "includedEventTypes": ["pod.started"], "retentionDays": 0 }
// after
"auditReadView": { "includedEventTypes": ["pod.started"], "retentionDays": 90 } Defensive patterns
Strategy: try-catch
Validate before calling
if (typeof av?.retentionDays !== 'number' || av.retentionDays < 1) {
throw new Error('set auditReadView.retentionDays to a positive day count');
} Type guard
function isValidRetentionDays(v: unknown): boolean {
return typeof v === 'number' && Number.isFinite(v) && v >= 1;
} Try / catch
try { validatePodTemplate(json); } catch (err) {
if (err instanceof PodTemplateValidationError && /retentionDays/.test(err.message)) {
// clamp or prompt for a positive retention, then re-validate
}
} Prevention
- Translate 'keep forever' conventions to an explicit large day count (e.g. 3650)
- Validate retention policy fields in the same pass as other audit config before shipping
When it happens
Trigger: A pod template with auditReadView.retentionDays set to 0 or a negative number. Non-numeric values fail earlier in requireNumber with a different message.
Common situations: Configs where 0 meant 'keep forever' or 'disabled' in a previous system; sign errors from spreadsheets (e.g. -90); expressing 'no audit retention' which this schema does not permit.
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
- bench.scheduleHours must be ≥1
- roomId may only contain [A-Za-z0-9_.\-:/@#]
- agents must have ≥1 entry
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/e126e45be7b9db7a.
Report an issue: GitHub.