{"record":{"id":"fafbefcfdf196543","repo":"ruvnet/ruflo","slug":"field-key-must-be-a-finite-number","errorCode":null,"errorMessage":"field \"${key}\" must be a finite number","messagePattern":"field \"(.+?)\" must be a finite number","errorType":"validation","errorClass":"PodTemplateValidationError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/business-pods/pod-schema.ts","lineNumber":104,"sourceCode":"\nconst PII_POLICIES: PiiPolicy[] = ['soc2', 'gdpr', 'hipaa', 'permissive'];\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction requireString(parent: Record<string, unknown>, key: string, path: string): string {\n  const v = parent[key];\n  if (typeof v !== 'string' || v.length === 0) {\n    throw new PodTemplateValidationError(`field \"${key}\" must be a non-empty string`, path);\n  }\n  return v;\n}\n\nfunction requireNumber(parent: Record<string, unknown>, key: string, path: string): number {\n  const v = parent[key];\n  if (typeof v !== 'number' || !Number.isFinite(v)) {\n    throw new PodTemplateValidationError(`field \"${key}\" must be a finite number`, path);\n  }\n  return v;\n}\n\nfunction requireBoolean(parent: Record<string, unknown>, key: string, path: string): boolean {\n  const v = parent[key];\n  if (typeof v !== 'boolean') {\n    throw new PodTemplateValidationError(`field \"${key}\" must be a boolean`, path);\n  }\n  return v;\n}\n\nfunction requireArray<T>(parent: Record<string, unknown>, key: string, path: string,\n                          itemValidator: (item: unknown, ipath: string) => T): T[] {\n  const v = parent[key];\n  if (!Array.isArray(v)) {\n    throw new PodTemplateValidationError(`field \"${key}\" must be an array`, path);\n  }","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/business-pods/pod-schema.ts#L86-L122","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n{ \"budgetUsdMonthly\": \"100\", \"budgetUsdPerRun\": \"2\" }\n// after\n{ \"budgetUsdMonthly\": 100, \"budgetUsdPerRun\": 2 }","handlingStrategy":"validation","validationCode":"function isFiniteNumberField(o: Record<string, unknown>, key: string): boolean {\n  return typeof o[key] === 'number' && Number.isFinite(o[key] as number);\n}\nfor (const k of ['budgetUsdMonthly', 'budgetUsdPerRun']) {\n  if (!isFiniteNumberField(template, k)) fail(`${k} must be a bare JSON number`);\n}","typeGuard":"function isFiniteNumber(v: unknown): v is number {\n  return typeof v === 'number' && Number.isFinite(v);\n}","tryCatchPattern":"try {\n  validatePodTemplate(template);\n} catch (e) {\n  if (e instanceof PodTemplateValidationError && e.message.includes('finite number')) {\n    fail(`Unquote the numeric field at ${e.path}`);\n  } else throw e;\n}","preventionTips":["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"],"tags":["pod","schema","validation","json","numbers"],"backgroundTag":"schema-validation-failed","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}