{"record":{"id":"a10d7bf500a5d0fc","repo":"mastra-ai/mastra","slug":"path-must-contain-only-finite-numbers","errorCode":null,"errorMessage":"${path} must contain only finite numbers.","messagePattern":"(.+?) must contain only finite numbers\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/builder/index.ts","lineNumber":130,"sourceCode":"  'tool',\n  'mapping',\n  'workflow',\n  'parallel',\n  'foreach',\n  'sleep',\n  'sleepUntil',\n  'conditional',\n  'loop',\n] as const;\n\nexport type WorkflowBuilderSupportedStepType = (typeof WORKFLOW_BUILDER_SUPPORTED_STEP_TYPES)[number];\n\nexport { WORKFLOW_BUILDER_AUTHORING_CONSTRAINTS, WORKFLOW_BUILDER_AUTHORING_PLAYBOOK } from './authoring-playbook';\n\nfunction normalizeJsonValue(value: unknown, path: string, seen: Set<object>): WorkflowBuilderJsonValue {\n  if (value === null || typeof value === 'string' || typeof value === 'boolean') return value;\n  if (typeof value === 'number') {\n    if (!Number.isFinite(value)) throw new TypeError(`${path} must contain only finite numbers.`);\n    return value;\n  }\n  if (typeof value !== 'object') throw new TypeError(`${path} must be JSON-safe.`);\n  if (seen.has(value)) throw new TypeError(`${path} must not contain cycles.`);\n  seen.add(value);\n  try {\n    if (Array.isArray(value)) return value.map((item, index) => normalizeJsonValue(item, `${path}.${index}`, seen));\n    if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {\n      throw new TypeError(`${path} must contain only plain objects.`);\n    }\n    const normalized: WorkflowBuilderJsonObject = {};\n    for (const [key, item] of Object.entries(value)) {\n      if (item !== undefined) normalized[key] = normalizeJsonValue(item, `${path}.${key}`, seen);\n    }\n    return normalized;\n  } finally {\n    seen.delete(value);\n  }","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/builder/index.ts#L112-L148","documentation":"Workflow builder input must be JSON-serializable. normalizeJsonValue() recursively validates values, and any number that is NaN, +Infinity, or -Infinity fails Number.isFinite() and triggers this TypeError naming the offending path. NaN/Infinity cannot round-trip through JSON, so the builder rejects them at the boundary.","triggerScenarios":"Passing data containing NaN, Infinity, or -Infinity into workflow builder APIs (e.g. default/params/config values), typically from a division by zero, parseInt failure, or a Math op returning NaN.","commonSituations":"Computing defaults at runtime (e.g. 1/0, parseInt(undefined)); deserializing values from a source that encoded Infinity as a bare token; stats/averages over empty arrays yielding NaN.","solutions":["Sanitize inputs with Number.isFinite checks and replace non-finite values with a defined fallback (0, null, or a sentinel)","Trace the reported `path` to find which field holds NaN/Infinity and fix the producing computation","If infinity is meaningful, encode it as a string or { finite: false } marker the schema accepts","Clamp or guard the arithmetic (avoid division by zero, coerce parseInt with Number.isNaN fallback)"],"exampleFix":"// before\nconst rate = total / count; // count = 0 → Infinity\nbuilder.withConfig({ rate });\n// after\nconst rate = count > 0 ? total / count : 0;\nif (!Number.isFinite(rate)) throw new Error('invalid rate');\nbuilder.withConfig({ rate });","handlingStrategy":"validation","validationCode":"function assertFiniteNumbers(obj, path = 'input') {\n  for (const [k, v] of Object.entries(obj)) {\n    if (typeof v === 'number' && !Number.isFinite(v)) throw new Error(`${path}.${k} is not finite`);\n    if (v && typeof v === 'object') assertFiniteNumbers(v, `${path}.${k}`);\n  }\n}\nassertFiniteNumbers(params);","typeGuard":"const isFiniteNumber = (v) => typeof v === 'number' && Number.isFinite(v);","tryCatchPattern":"try {\n  builder.withParams(raw);\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('must contain only finite numbers')) {\n    logger.error('Non-finite number at', e.message.split(' ')[0]);\n  } else throw e;\n}","preventionTips":["Guard division: check divisors for 0","Check Number.isNaN after parseInt/parseFloat with fallbacks","Sanitize computed defaults before passing to builder APIs","Treat the thrown `path` message as your pointer to the bad field"],"tags":["validation","json","workflow-builder"],"backgroundTag":"non-finite-number-in-json","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}