{"record":{"id":"1a46d92f588a8923","repo":"ruvnet/ruflo","slug":"pod-template-at-budgetusdperrun-must-not-exceed","errorCode":null,"errorMessage":"pod-template at /: budgetUsdPerRun must not exceed budgetUsdMonthly","messagePattern":"pod-template at /: budgetUsdPerRun must not exceed budgetUsdMonthly","errorType":"validation","errorClass":"PodTemplateValidationError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/business-pods/pod-schema.ts","lineNumber":236,"sourceCode":"  }\n  const bench = validatePodBench(json.bench, '/bench');\n  const piiPolicy = requireString(json, 'piiPolicy', '/');\n  if (!PII_POLICIES.includes(piiPolicy as PiiPolicy)) {\n    throw new PodTemplateValidationError(\n      `piiPolicy must be one of: ${PII_POLICIES.join(', ')}`,\n      '/',\n    );\n  }\n  const budgetUsdMonthly = requireNumber(json, 'budgetUsdMonthly', '/');\n  if (budgetUsdMonthly < 0) {\n    throw new PodTemplateValidationError('budgetUsdMonthly must be ≥0', '/');\n  }\n  const budgetUsdPerRun = requireNumber(json, 'budgetUsdPerRun', '/');\n  if (budgetUsdPerRun < 0) {\n    throw new PodTemplateValidationError('budgetUsdPerRun must be ≥0', '/');\n  }\n  if (budgetUsdMonthly > 0 && budgetUsdPerRun > budgetUsdMonthly) {\n    throw new PodTemplateValidationError(\n      'budgetUsdPerRun must not exceed budgetUsdMonthly',\n      '/',\n    );\n  }\n  const preferLocalExecution = requireBoolean(json, 'preferLocalExecution', '/');\n  const cronSchedule = requireString(json, 'cronSchedule', '/');\n  if (!CRON_RE.test(cronSchedule)) {\n    throw new PodTemplateValidationError(\n      'cronSchedule must be a POSIX cron expression (5 or 6 fields)',\n      '/',\n    );\n  }\n  const auditReadView = validateAuditReadView(json.auditReadView, '/auditReadView');\n\n  let reservationExpiryMs: number | undefined;\n  if (json.reservationExpiryMs !== undefined) {\n    const v = requireNumber(json, 'reservationExpiryMs', '/');\n    // ADR-164.1 §3.2 — bounded to [5_000, 300_000] ms.","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/business-pods/pod-schema.ts#L218-L254","documentation":"A cross-field budget sanity check in validatePodTemplate(): when budgetUsdMonthly > 0 (a monthly cap exists) and budgetUsdPerRun exceeds it, the template is rejected — a single run could never legally execute under the monthly cap. The 'pod-template at /:' prefix seen in logs is the caller (business_pod_validate / pod-tick) formatting the thrown message with its JSON-pointer path; the thrown message itself is 'budgetUsdPerRun must not exceed budgetUsdMonthly'.","triggerScenarios":"budgetUsdMonthly: 10 with budgetUsdPerRun: 50 — one run would blow the monthly cap 5x. Both values individually pass their >= 0 checks; only the relation fails. Note budgetUsdMonthly: 0 disables this check entirely.","commonSituations":"Units mismatch (monthly in cents, per-run in dollars); fields swapped when filling the template; per-run cost estimates from a pricier model pasted into a template with a small monthly cap.","solutions":["Raise budgetUsdMonthly to at least budgetUsdPerRun (realistically per-run * expected runs)","Lower budgetUsdPerRun to fit within the monthly cap","Set budgetUsdMonthly to 0 only if you genuinely want no monthly cap (this disables the cross-check)"],"exampleFix":"// before\n\"budgetUsdMonthly\": 10, \"budgetUsdPerRun\": 50\n// after\n\"budgetUsdMonthly\": 500, \"budgetUsdPerRun\": 50","handlingStrategy":"validation","validationCode":"const { budgetUsdMonthly: m, budgetUsdPerRun: r } = json;\nif (typeof m === 'number' && typeof r === 'number' && m > 0 && r > m) {\n  throw new Error(`per-run budget ${r} exceeds monthly cap ${m}`);\n}","typeGuard":"function budgetsAreConsistent(m: unknown, r: unknown): boolean {\n  return !(typeof m === 'number' && typeof r === 'number' && m > 0 && r > m);\n}","tryCatchPattern":"try { validatePodTemplate(json); } catch (err) {\n  if (err instanceof PodTemplateValidationError && /must not exceed/.test(err.message)) {\n    // either raise the monthly cap or lower per-run; monthly=0 disables the check\n  }\n}","preventionTips":["Derive budgetUsdPerRun from budgetUsdMonthly / expected-runs in your generator","Double-check unit consistency (dollars vs cents) between the two fields"],"tags":["schema-validation","business-pods","budget","cross-field-validation","configuration"],"backgroundTag":"schema-validation-failed","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}