ruvnet/ruflo · error · PodTemplateValidationError
field "${key}" must be a finite number
Error message
field "${key}" must be a finite number What it means
Pod template validator's requireNumber() throws PodTemplateValidationError when a required numeric field is missing, not a number, or non-finite (NaN/Infinity). Applies to fields like budgetUsdMonthly, budgetUsdPerRun, bench.scheduleHours, and auditReadView.retentionDays. JSON cannot legally encode NaN/Infinity, so non-finite here means a string, boolean, null, or missing value.
Source
Thrown at v3/@claude-flow/cli/src/business-pods/pod-schema.ts:104
const PII_POLICIES: PiiPolicy[] = ['soc2', 'gdpr', 'hipaa', 'permissive'];
function isObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
}
function requireString(parent: Record<string, unknown>, key: string, path: string): string {
const v = parent[key];
if (typeof v !== 'string' || v.length === 0) {
throw new PodTemplateValidationError(`field "${key}" must be a non-empty string`, path);
}
return v;
}
function requireNumber(parent: Record<string, unknown>, key: string, path: string): number {
const v = parent[key];
if (typeof v !== 'number' || !Number.isFinite(v)) {
throw new PodTemplateValidationError(`field "${key}" must be a finite number`, path);
}
return v;
}
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);
}View on GitHub (pinned to fa13ee4ad6)
Solutions
- Make the named field an unquoted JSON number: "budgetUsdMonthly": 100 not "100"
- If generating templates programmatically, coerce with Number() and validate before writing
- Check the error's path to find nested numeric fields (bench.scheduleHours, auditReadView.retentionDays)
- Lint templates in CI with the same validator to catch regressions
Example fix
// before
{ "budgetUsdMonthly": "100", "budgetUsdPerRun": "2" }
// after
{ "budgetUsdMonthly": 100, "budgetUsdPerRun": 2 } Defensive patterns
Strategy: validation
Validate before calling
function isFiniteNumberField(o: Record<string, unknown>, key: string): boolean {
return typeof o[key] === 'number' && Number.isFinite(o[key] as number);
}
for (const k of ['budgetUsdMonthly', 'budgetUsdPerRun']) {
if (!isFiniteNumberField(template, k)) fail(`${k} must be a bare JSON number`);
} Type guard
function isFiniteNumber(v: unknown): v is number {
return typeof v === 'number' && Number.isFinite(v);
} Try / catch
try {
validatePodTemplate(template);
} catch (e) {
if (e instanceof PodTemplateValidationError && e.message.includes('finite number')) {
fail(`Unquote the numeric field at ${e.path}`);
} else throw e;
} Prevention
- Keep numbers unquoted in template JSON/YAML sources
- When generating from YAML or form input, coerce with Number() and validate before writing
- Watch nested numerics: bench.scheduleHours and auditReadView.retentionDays are also checked
When it happens
Trigger: validatePodTemplate() with a numeric field supplied as a string ("budgetUsdMonthly": "100"), left undefined, set to null/true, or parsed from YAML/JSON5 where unquoted NaN sneaks in. The failing key name appears in the message.
Common situations: Templates authored in YAML then converted to JSON, where numeric-looking strings stay quoted; config management (helm values, terraform jsonencode) injecting everything as strings; template generated from user form input without coercion.
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 boolean
- field "${key}" must be an array
- agent must be an object
- bench must be an object
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/fafbefcfdf196543.
Report an issue: GitHub.