alibaba/spring-ai-alibaba · error · ModelCallLimitExceededException
Model call limits exceeded: ${threadCount}/${threadLimit} th
Error message
Model call limits exceeded: ${threadCount}/${threadLimit} thread, ${runCount}/${runLimit} run What it means
ModelCallLimitHook.beforeModel() tracks model call counts per thread and per run. When a configured limit is reached and exitBehavior is ExitBehavior.ERROR, it throws ModelCallLimitExceededException (whose message reports counts like "3/3 thread, 5/5 run") before another LLM call is made, protecting against runaway token spend.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/modelcalllimit/ModelCallLimitHook.java:74
public static Builder builder() {
return new Builder();
}
@Override
public CompletableFuture<Map<String, Object>> beforeModel(OverAllState state, RunnableConfig config) {
// Read current counts from context
int threadModelCallCount = config.context().containsKey(THREAD_COUNT_KEY)
? (int) config.context().get(THREAD_COUNT_KEY) : 0;
int runModelCallCount = config.context().containsKey(RUN_COUNT_KEY)
? (int) config.context().get(RUN_COUNT_KEY) : 0;
// Check if limits are already exceeded (before making the call)
boolean threadLimitExceeded = threadLimit != null && threadModelCallCount >= threadLimit;
boolean runLimitExceeded = runLimit != null && runModelCallCount >= runLimit;
if (threadLimitExceeded || runLimitExceeded) {
if (exitBehavior == ExitBehavior.ERROR) {
throw new ModelCallLimitExceededException(
threadModelCallCount,
runModelCallCount,
threadLimit,
runLimit
);
}
else if (exitBehavior == ExitBehavior.END) {
// Add message indicating limit was exceeded and jump to end
String message = buildLimitExceededMessage(
threadModelCallCount,
runModelCallCount,
threadLimit,
runLimit
);
List<Message> messages = new ArrayList<>();
messages.add(new AssistantMessage(message));
View on GitHub (pinned to f82da0b50f)
Solutions
- Catch ModelCallLimitExceededException and treat it as a terminal state (summarize, notify user, or reset the thread).
- Raise threadLimit/runLimit in the hook builder if the limit was set too aggressively.
- Switch exitBehavior to a non-ERROR value (e.g. END) if exceeding the limit should stop gracefully instead of throwing.
- Reset or start a new thread when the per-thread count is exhausted.
Example fix
// before ModelCallLimitHook hook = ModelCallLimitHook.builder().threadLimit(10).runLimit(5).exitBehavior(ExitBehavior.ERROR).build(); // after ModelCallLimitHook hook = ModelCallLimitHook.builder().threadLimit(50).runLimit(20).exitBehavior(ExitBehavior.END).build();
Defensive patterns
Strategy: try-catch
Validate before calling
if (hook instanceof ModelCallLimitHook) { /* verify limits vs expected agent loop length */
int expectedCalls = estimateModelCalls(agent);
assert expectedCalls < configuredLimit; } Try / catch
try {
agent.invoke(inputs);
} catch (ModelCallLimitExceededException e) {
log.warn("Limit hit: {} thread, {} run", e.getThreadCount(), e.getRunCount());
// terminate gracefully / notify / checkpoint
} Prevention
- Size limits from measured call counts of your agent loops
- Prefer ExitBehavior.END for graceful stop in production
- Alert/monitor model call counters before limits trip
- Reset threads periodically for long-lived conversations
When it happens
Trigger: Running an agent with ModelCallLimitHook configured with threadLimit and/or runLimit and ExitBehavior.ERROR, where the model call count for the thread or current run reaches the limit before the next model invocation.
Common situations: Long-running conversational threads that accumulate calls across runs and hit threadLimit; loop/iterative agents that call the model many times per run and hit runLimit; setting low limits for cost control in tests then deploying unchanged to production.
Related errors
- At least one limit must be specified (threadLimit or runLimi
- Failed to initialize shell session
- Tool call limits exceeded: ${threadCount}/${threadLimit} thr
- Elastic search index name must be provided
- Param Not Support Object
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/018fb1fde68402ea.
Report an issue: GitHub.