alibaba/spring-ai-alibaba · error · IllegalArgumentException

ReactAgent requires model configuration in handle

Error message

ReactAgent requires model configuration in handle

What it means

ReactAgentProvider.validateSpecific() throws this when a react_agent's "handle" section has no "model" entry. A ReactAgent needs an LLM to run its reasoning loop, so the model configuration is mandatory. The DSL passes structural validation but is semantically incomplete for generation.

Solutions

  1. Add a "model" entry inside the "handle" object of the react_agent config
  2. Ensure the selected model is available in the target environment (e.g. a DashScope model name)
  3. If the agent is meant to be model-less, use a non-React agent type (e.g. a plain workflow node)

Example fix

// before
{"type": "react_agent", "name": "assistant", "handle": {"tools": ["search"]}}
// after
{"type": "react_agent", "name": "assistant", "handle": {"model": "qwen-max", "tools": ["search"]}}
Defensive patterns

Strategy: validation

Validate before calling

Map<String,Object> handle = (Map<String,Object>) config.get("handle");
if (handle == null || handle.get("model") == null) {
    throw new IllegalArgumentException("react_agent handle requires a 'model' entry");
}

Type guard

static boolean hasModel(Map<String,Object> cfg) {
    return cfg.get("handle") instanceof Map<?,?> h && h.get("model") != null;
}

Try / catch

try {
    provider.validateDSL(root);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("requires model configuration")) {
        // prompt user to pick a model for the react_agent
    }
}

Prevention

When it happens

Trigger: validateDSL calls validateSpecific(root); requireHandle(root) succeeds but handle.get("model") == null — the handle section omits the model key entirely.

Common situations: Copying a tool-only or workflow sub-agent config into a react_agent; a UI export that strips the model when no default model is selected; deleting a model reference that pointed to an unavailable model.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/builder/generator/service/generator/agent/impl/ReactAgentProvider.java:165

				"import com.alibaba.cloud.ai.graph.state.strategy.ReplaceStrategy;",
				"import org.springframework.ai.chat.model.ChatModel;",
				"import org.springframework.context.annotation.Bean;",
				"import org.springframework.stereotype.Component;",
				hasResolver ? "import org.springframework.beans.factory.ObjectProvider;" : null,
				hasResolver ? "import org.springframework.ai.tool.resolution.ToolCallbackResolver;" : null,
				"import java.util.*;")
			.code(code.toString())
			.var(var)
			.resolver(hasResolver);
	}

	@Override
	protected void validateSpecific(Map<String, Object> root) {
		// ReactAgent 必须有 model 配置
		Map<String, Object> handle = requireHandle(root);

		if (handle.get("model") == null) {
			throw new IllegalArgumentException("ReactAgent requires model configuration in handle");
		}

		// 如果有 tools,检查相关配置
		if (handle.get("tools") instanceof List<?> tools && !tools.isEmpty()) {
			// 检查 tools 是否为空字符串
			for (Object tool : tools) {
				if (tool instanceof String s && s.trim().isEmpty()) {
					throw new IllegalArgumentException("ReactAgent tool names cannot be empty");
				}
			}
		}

		// 检查 max_iterations 如果存在,必须是正数
		Object maxIterations = handle.get("max_iterations");
		if (maxIterations != null) {
			requirePositiveNumber(maxIterations, "max_iterations", 1);
		}
	}

View on GitHub (pinned to f82da0b50f)