require-max-steps
This rule identifies AI SDK calls that use tools but don't specify a `maxSteps` limit. Without limits, AI agents can enter infinite loops calling tools repeated
Prevents infinite tool calling loops in multi-step agents.
📊 Rule Details
| Property | Value |
|---|---|
| Type | suggestion |
| Severity | 🟡 HIGH |
| OWASP LLM | LLM10: Unbounded Consumption |
| CWE | CWE-834: Excessive Iteration |
| CVSS | 6.5 |
| Config Default | warn (recommended), error (strict) |
🔍 What This Rule Detects
This rule identifies AI SDK calls that use tools but don't specify a maxSteps limit. Without limits, AI agents can enter infinite loops calling tools repeatedly.
❌ Incorrect Code
// Tools without maxSteps
await generateText({
model: openai('gpt-4'),
prompt: 'Research and summarize',
tools: {
search: searchTool,
summarize: summarizeTool,
},
});
// Multi-tool agent without limit
await streamText({
model: anthropic('claude-3'),
prompt: 'Complete the task',
tools: { search, write, deploy },
});✅ Correct Code
// With maxSteps limit
await generateText({
model: openai('gpt-4'),
prompt: 'Research and summarize',
tools: {
search: searchTool,
summarize: summarizeTool,
},
maxSteps: 5,
});
// Bounded agent
await streamText({
model: anthropic('claude-3'),
prompt: 'Complete the task',
tools: { search, write, deploy },
maxSteps: 10,
});⚙️ Options
| Option | Type | Default | Description |
|---|---|---|---|
maxRecommended | number | undefined | Warn if maxSteps exceeds this value |
🛡️ Why This Matters
Unbounded tool loops can cause:
- Infinite loops - AI keeps calling tools forever
- Cost explosion - Each tool call may trigger additional API calls
- Resource exhaustion - Downstream services overwhelmed
- Data corruption - Repeated mutations without checks
🔗 Related Rules
require-max-tokens- Limit token consumptionrequire-tool-confirmation- Require confirmation
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Options from Variable
Why: Options stored in variables are not analyzed.
// ❌ NOT DETECTED - Options from variable
const opts = { model: openai('gpt-4'), tools, prompt: 'Hello' }; // No maxSteps
await generateText(opts);Mitigation: Use inline options. Always specify maxSteps with tools.
Tools from Variable
Why: Tools added from variables may not trigger detection.
// ❌ NOT DETECTED - Tools from variable
const tools = getToolset();
await generateText({ ..., tools }); // Has tools, needs maxStepsMitigation: Always set maxSteps when using tools.
Conditional Tool Usage
Why: Conditionally added tools may not be detected.
// ❌ NOT DETECTED - Conditional tools
const options = { model, prompt };
if (useTools) options.tools = toolset; // maxSteps also needed!
await generateText(options);Mitigation: Set maxSteps whenever tools may be used.
Wrapper Functions
Why: Custom wrappers may hide tool usage.
// ❌ NOT DETECTED - Wrapper with tools
await myAgentGenerate(prompt); // Wrapper adds tools internallyMitigation: Apply rule to wrapper implementations.
📚 References
require-error-handling
This rule identifies AI SDK calls that aren't wrapped in try-catch blocks. AI calls can fail due to rate limits, network issues, or content filtering.
require-max-tokens
This rule identifies AI SDK calls that don't specify a `maxTokens` limit. Without limits, AI responses can consume excessive tokens, leading to high costs and p