Interlace ESLint
ESLint Interlace
Vercel AIRules

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

PropertyValue
Typesuggestion
Severity🟡 HIGH
OWASP LLMLLM10: Unbounded Consumption
CWECWE-834: Excessive Iteration
CVSS6.5
Config Defaultwarn (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

OptionTypeDefaultDescription
maxRecommendednumberundefinedWarn 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

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 maxSteps

Mitigation: 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 internally

Mitigation: Apply rule to wrapper implementations.

📚 References

On this page