JuliusBrussee/caveman · error · Error
cave_mastra_max_steps_invalid
cave_mastra_max_steps_invalid
Error message
cave_mastra_max_steps_invalid
What it means
`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.
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
Example fix
// before
const maxSteps = Number(cfg.get('MAXSTEPS')); // NaN when unset
createMastraAdapter(identity, agent, { maxSteps });
// after
const raw = cfg.get('MAXSTEPS');
const maxSteps = raw === undefined ? undefined : Number.parseInt(raw, 10);
if (maxSteps !== undefined && (!Number.isSafeInteger(maxSteps) || maxSteps <= 0)) {
throw new Error(`invalid MAXSTEPS: ${raw}`);
}
createMastraAdapter(identity, agent, maxSteps === undefined ? {} : { maxSteps }); Defensive patterns
Strategy: type-guard
Validate before calling
const raw = cfg.get('MAXSTEPS');
const maxSteps = raw === undefined || raw === '' ? undefined : Number.parseInt(raw, 10);
if (maxSteps !== undefined && !isPositiveSafeInteger(maxSteps)) {
throw new Error(`invalid MAXSTEPS config: ${JSON.stringify(raw)}`);
}
return createMastraAdapter(identity, agent, maxSteps === undefined ? {} : { maxSteps }); Type guard
function isPositiveSafeInteger(v: unknown): v is number {
return typeof v === 'number' && Number.isSafeInteger(v) && v > 0;
} Prevention
- 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
When it happens
Trigger: `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`.
Common situations: Reading limits from env vars or config files without integer coercion; passing 0 to disable; arithmetic producing non-integer values.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- caveman agent: context id is required
- caveman agent: memory recallBudget must be a non-negative…
- invalid_deadline
- maxLoadedTools must be a positive integer
- maxLoadedTools must be at least the alwaysLoad tool count
AI-assisted analysis of JuliusBrussee/caveman@766dce6b13 (2026-08-18).
Data as JSON: /api/errors/13ec1893e15c40c0.
Report an issue: GitHub.
Appendix: source
Thrown at packages/agent/src/adapters.ts:302
error?: unknown;
finishReason?: unknown;
response?: { modelId?: unknown };
}>;
}
export interface MastraAdapterOptions {
/** Mastra's per-generate maximum number of sequential LLM calls. */
maxSteps?: number;
}
export function createMastraAdapter(
identity: HarnessAdapterIdentity,
agent: MastraAgentBinding,
options: MastraAdapterOptions = {},
): HarnessAdapter {
const maxSteps = options.maxSteps;
if (maxSteps !== undefined && (!Number.isSafeInteger(maxSteps) || maxSteps <= 0)) {
throw new Error("cave_mastra_max_steps_invalid");
}
assertSupportedUpstream(identity, MASTRA_VERSION, "mastra", "@mastra/core");
return createHarnessAdapter("mastra", identity, {
package: "@mastra/core/agent",
class: "Agent",
method: "generate",
usage: "FullOutput.totalUsage",
...(maxSteps === undefined ? {} : { preExecutionControls: { maxSteps } }),
}, async (request) => {
const startedAt = performance.now();
const response = await agent.generate(request.prompt, {
maxProcessorRetries: 0,
runId: request.runID,
...(maxSteps === undefined ? {} : { maxSteps }),
...(request.signal === undefined ? {} : { abortSignal: request.signal }),
});
if (response.error !== undefined || terminalFinishReason(response.finishReason) === false) {
throw new Error("cave_mastra_terminal_failure");View on GitHub (pinned to 766dce6b13)