{"record":{"id":"83ee168052968aae","repo":"ruvnet/ruflo","slug":"selectagentbackend-pod-budgetusdmonthly-must-be-a","errorCode":null,"errorMessage":"selectAgentBackend: pod.budgetUsdMonthly must be a finite number (validate via pod-schema first)","messagePattern":"selectAgentBackend: pod\\.budgetUsdMonthly must be a finite number \\(validate via pod-schema first\\)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/business-pods/domain-affinity-policy.ts","lineNumber":61,"sourceCode":"/**\n * Decide which backend `@metaharness/router` should prefer for a pod tick.\n *\n * @param pod  A validated PodTemplate. Validation is the caller's\n *             responsibility; this function will throw on malformed input\n *             (specifically on missing `preferLocalExecution` or\n *             `budgetUsdMonthly`).\n */\nexport function selectAgentBackend(pod: PodTemplate): BackendDecision {\n  if (pod === null || typeof pod !== 'object') {\n    throw new TypeError('selectAgentBackend: pod must be a validated PodTemplate object');\n  }\n  if (typeof pod.preferLocalExecution !== 'boolean') {\n    throw new TypeError(\n      'selectAgentBackend: pod.preferLocalExecution must be boolean (validate via pod-schema first)',\n    );\n  }\n  if (typeof pod.budgetUsdMonthly !== 'number' || !Number.isFinite(pod.budgetUsdMonthly)) {\n    throw new TypeError(\n      'selectAgentBackend: pod.budgetUsdMonthly must be a finite number (validate via pod-schema first)',\n    );\n  }\n\n  if (pod.preferLocalExecution) {\n    return {\n      backend: 'local-stdio',\n      reason: `pod \"${pod.name}\" preferLocalExecution=true — domain-affinity policy pins to local stdio`,\n    };\n  }\n  if (pod.budgetUsdMonthly >= CLOUD_BUDGET_THRESHOLD_USD) {\n    return {\n      backend: 'cloud-managed',\n      reason:\n        `pod \"${pod.name}\" preferLocalExecution=false and budgetUsdMonthly=${pod.budgetUsdMonthly} ` +\n        `>= ${CLOUD_BUDGET_THRESHOLD_USD} — routes to cloud Managed Agents`,\n    };\n  }","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/business-pods/domain-affinity-policy.ts#L43-L79","documentation":"TypeError in selectAgentBackend() when pod.budgetUsdMonthly is missing, not a number, or not finite (NaN/±Infinity). This field is the threshold input for the routing decision (>= 50 routes to cloud-managed). A malformed value means the pod was not validated via validatePodTemplate() which enforces a finite number.","triggerScenarios":"Calling selectAgentBackend(pod) where pod.budgetUsdMonthly is undefined, a string like \"50\", NaN, or Infinity.","commonSituations":"Budget read from config as a string and not coerced; a missing field in a hand-written template; Number('unlimited') producing NaN; a computation that overflows to Infinity.","solutions":["Run validatePodTemplate() — requireNumber() checks typeof === 'number' and Number.isFinite() before selectAgentBackend ever sees the value","If constructing the object in code, ensure budgetUsdMonthly is a finite number literal"],"exampleFix":"// before:\nselectAgentBackend({ ...pod, budgetUsdMonthly: Number(\"unlimited\") }); // NaN, throws\n\n// after:\nconst pod = validatePodTemplate(parsed);\nselectAgentBackend(pod); // budgetUsdMonthly is a finite number","handlingStrategy":"validation","validationCode":"import { validatePodTemplate } from '@claude-flow/cli/business-pods/pod-schema';\n\n// validatePodTemplate's requireNumber() enforces Number.isFinite for\n// budgetUsdMonthly before selectAgentBackend ever sees the value.\nconst pod = validatePodTemplate(parsedJson);\nselectAgentBackend(pod);","typeGuard":"function hasValidBudgetUsdMonthly(pod: unknown): boolean {\n  if (typeof pod !== 'object' || pod === null) return false;\n  const v = (pod as { budgetUsdMonthly?: unknown }).budgetUsdMonthly;\n  return typeof v === 'number' && Number.isFinite(v);\n}","tryCatchPattern":null,"preventionTips":["Validate pod templates via validatePodTemplate() before routing","Ensure budget fields are written as bare JSON numbers, not quoted strings","Guard against NaN from Number() coercion of non-numeric config values"],"tags":["routing","validation","pod-template","numbers"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}