{"record":{"id":"13ec1893e15c40c0","repo":"JuliusBrussee/caveman","slug":"cave-mastra-max-steps-invalid","errorCode":"cave_mastra_max_steps_invalid","errorMessage":"cave_mastra_max_steps_invalid","messagePattern":"cave_mastra_max_steps_invalid","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/agent/src/adapters.ts","lineNumber":302,"sourceCode":"    error?: unknown;\n    finishReason?: unknown;\n    response?: { modelId?: unknown };\n  }>;\n}\n\nexport interface MastraAdapterOptions {\n  /** Mastra's per-generate maximum number of sequential LLM calls. */\n  maxSteps?: number;\n}\n\nexport function createMastraAdapter(\n  identity: HarnessAdapterIdentity,\n  agent: MastraAgentBinding,\n  options: MastraAdapterOptions = {},\n): HarnessAdapter {\n  const maxSteps = options.maxSteps;\n  if (maxSteps !== undefined && (!Number.isSafeInteger(maxSteps) || maxSteps <= 0)) {\n    throw new Error(\"cave_mastra_max_steps_invalid\");\n  }\n  assertSupportedUpstream(identity, MASTRA_VERSION, \"mastra\", \"@mastra/core\");\n  return createHarnessAdapter(\"mastra\", identity, {\n    package: \"@mastra/core/agent\",\n    class: \"Agent\",\n    method: \"generate\",\n    usage: \"FullOutput.totalUsage\",\n    ...(maxSteps === undefined ? {} : { preExecutionControls: { maxSteps } }),\n  }, async (request) => {\n    const startedAt = performance.now();\n    const response = await agent.generate(request.prompt, {\n      maxProcessorRetries: 0,\n      runId: request.runID,\n      ...(maxSteps === undefined ? {} : { maxSteps }),\n      ...(request.signal === undefined ? {} : { abortSignal: request.signal }),\n    });\n    if (response.error !== undefined || terminalFinishReason(response.finishReason) === false) {\n      throw new Error(\"cave_mastra_terminal_failure\");","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/766dce6b1394ebb56a3090748d5a0240a5aefb36/packages/agent/src/adapters.ts#L284-L320","documentation":"`createMastraAdapter` validates the optional `options.maxSteps`: it must be `undefined` or satisfy `Number.isSafeInteger(maxSteps) && maxSteps > 0`. Zero, negatives, fractions, `NaN`, `Infinity`, and non-numbers (including numeric strings read from env/config) throw `cave_mastra_max_steps_invalid` at adapter construction, before any generation happens. To use Mastra's default, omit the option entirely rather than passing 0.","triggerScenarios":"`maxSteps: Number(process.env.MASTRA_MAX_STEPS)` when the variable is unset (NaN); a JSON config supplying `\"maxSteps\": \"25\"` as a string; `maxSteps: 0` intended to mean \"no limit\"; a computed float like `12.5`.","commonSituations":"Reading limits from env vars or config files without integer coercion; passing 0 to disable; arithmetic producing non-integer values.","solutions":["Parse config strictly: `Number.parseInt(raw, 10)` then check `Number.isSafeInteger(v) && v > 0` before passing","Omit `maxSteps` entirely when you want Mastra's default","Validate at config-load time so the failure names the config key, not the adapter factory"],"exampleFix":"// before\nconst maxSteps = Number(cfg.get('MAXSTEPS')); // NaN when unset\ncreateMastraAdapter(identity, agent, { maxSteps });\n// after\nconst raw = cfg.get('MAXSTEPS');\nconst maxSteps = raw === undefined ? undefined : Number.parseInt(raw, 10);\nif (maxSteps !== undefined && (!Number.isSafeInteger(maxSteps) || maxSteps <= 0)) {\n  throw new Error(`invalid MAXSTEPS: ${raw}`);\n}\ncreateMastraAdapter(identity, agent, maxSteps === undefined ? {} : { maxSteps });","handlingStrategy":"type-guard","validationCode":"const raw = cfg.get('MAXSTEPS');\nconst maxSteps = raw === undefined || raw === '' ? undefined : Number.parseInt(raw, 10);\nif (maxSteps !== undefined && !isPositiveSafeInteger(maxSteps)) {\n  throw new Error(`invalid MAXSTEPS config: ${JSON.stringify(raw)}`);\n}\nreturn createMastraAdapter(identity, agent, maxSteps === undefined ? {} : { maxSteps });","typeGuard":"function isPositiveSafeInteger(v: unknown): v is number {\n  return typeof v === 'number' && Number.isSafeInteger(v) && v > 0;\n}","tryCatchPattern":null,"preventionTips":["Parse numeric config with Number.parseInt and validate before passing it to the adapter","Omit maxSteps entirely for Mastra's default — never pass 0 to mean 'no limit'","Validate at config-load time so errors name the config key"],"tags":["typescript","mastra","configuration","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"766dce6b1394ebb56a3090748d5a0240a5aefb36","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}