{"record":{"id":"5ae8a3094e0fae42","repo":"ruvnet/ruflo","slug":"pod-template-at-path-budgetusdmonthly-must-be","errorCode":null,"errorMessage":"pod-template at ${path}: budgetUsdMonthly must be ≥0","messagePattern":"pod-template at (.+?): budgetUsdMonthly must be ≥0","errorType":"validation","errorClass":"PodTemplateValidationError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/business-pods/pod-schema.ts","lineNumber":229,"sourceCode":"        tp,\n      );\n    }\n    return t;\n  });\n  if (allowedMcpTools.length === 0) {\n    throw new PodTemplateValidationError('allowedMcpTools must have ≥1 entry', '/');\n  }\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    );","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/business-pods/pod-schema.ts#L211-L247","documentation":"Thrown by validatePodTemplate() when budgetUsdMonthly is a valid finite number but is negative. The monthly budget is a hard cap on pod spending; 0 means unlimited (not recommended but allowed), while negative values are nonsensical.","triggerScenarios":"The budgetUsdMonthly field is set to any negative number (e.g. -1, -100.50). The requireNumber helper already verified it is a finite number, so this is purely a sign check.","commonSituations":"A budget was entered as a credit or refund notation; a sign error in a calculation that produced the template; a placeholder value of -1 was used to mean 'unset'.","solutions":["Set budgetUsdMonthly to 0 for unlimited, or a positive dollar amount (e.g. 500)","If the intent was 'no budget', use 0 rather than a negative sentinel"],"exampleFix":"// before\n{ \"budgetUsdMonthly\": -1 }\n\n// after\n{ \"budgetUsdMonthly\": 0 }","handlingStrategy":"validation","validationCode":"if (typeof template.budgetUsdMonthly !== 'number' || template.budgetUsdMonthly < 0) {\n  throw new Error('budgetUsdMonthly must be >= 0 (use 0 for unlimited)');\n}","typeGuard":"function isValidMonthlyBudget(v: unknown): boolean {\n  return typeof v === 'number' && Number.isFinite(v) && v >= 0;\n}","tryCatchPattern":"try {\n  validatePodTemplate(json);\n} catch (e) {\n  if (e instanceof PodTemplateValidationError && e.message.includes('budgetUsdMonthly')) {\n    // Set budgetUsdMonthly to 0 or a positive number\n  }\n}","preventionTips":["Use 0 for unlimited budget, never a negative sentinel","Ensure the value is a JSON number, not a string","Verify the unit is USD, not cents"],"tags":["pod-template","validation","schema","budget"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}