alibaba/spring-ai-alibaba · error · IllegalArgumentException

At least one limit must be specified (threadLimit or runLimi

Error message

At least one limit must be specified (threadLimit or runLimit)

What it means

ModelCallLimitHook.Builder.build() validates that at least one of threadLimit or runLimit is set. Building a hook with both null would produce a hook that can never trigger, so IllegalArgumentException is thrown at construction time.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/modelcalllimit/ModelCallLimitHook.java:169

		public Builder threadLimit(Integer threadLimit) {
			this.threadLimit = threadLimit;
			return this;
		}

		public Builder runLimit(Integer runLimit) {
			this.runLimit = runLimit;
			return this;
		}

		public Builder exitBehavior(ExitBehavior exitBehavior) {
			this.exitBehavior = exitBehavior;
			return this;
		}

		public ModelCallLimitHook build() {
			if (threadLimit == null && runLimit == null) {
				throw new IllegalArgumentException("At least one limit must be specified (threadLimit or runLimit)");
			}
			return new ModelCallLimitHook(this);
		}
	}
}

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Call .threadLimit(n) and/or .runLimit(n) on the builder before build().
  2. If limits come from configuration, validate the config values are non-null before building the hook.
  3. Skip registering the hook entirely when no limit is configured, instead of building an empty one.

Example fix

// before
ModelCallLimitHook hook = ModelCallLimitHook.builder().exitBehavior(ExitBehavior.ERROR).build();
// after
ModelCallLimitHook hook = ModelCallLimitHook.builder().threadLimit(20).exitBehavior(ExitBehavior.ERROR).build();
Defensive patterns

Strategy: validation

Validate before calling

if (threadLimit == null && runLimit == null) {
    throw new IllegalStateException("Configure threadLimit or runLimit before building ModelCallLimitHook");
}

Prevention

When it happens

Trigger: Calling ModelCallLimitHook.builder().build() (optionally after setting only exitBehavior or other non-limit options) without calling threadLimit(...) or runLimit(...).

Common situations: Copy-pasting builder code and deleting the limit lines; conditionally setting limits but having both branches skipped; refactoring where limits moved to config that failed to load.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/04649d2c3384ecde. Report an issue: GitHub.