chinabugotech/hutool · error · IllegalArgumentException
Unsupported model:
Error message
Unsupported model:
What it means
Thrown by the AIConfigBuilder constructor when AIConfigRegistry.getConfigClass(modelName) returns null. The registry is populated from Java SPI (ServiceLoaderUtil.load(AIConfig.class)) keyed by config.getModelName().toLowerCase(). A null result means no AIConfig implementation is registered for that vendor name. This is the config-side mirror of error 0.
Source
Thrown at hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigBuilder.java:42
*
* @author elichow
* @since 5.8.38
*/
public class AIConfigBuilder {
private final AIConfig config;
/**
* 构造
*
* @param modelName 模型厂商的名称(注意不是指具体的模型)
*/
public AIConfigBuilder(final String modelName) {
try {
// 获取配置类
final Class<? extends AIConfig> configClass = AIConfigRegistry.getConfigClass(modelName);
if (configClass == null) {
throw new IllegalArgumentException("Unsupported model: " + modelName);
}
// 使用反射创建实例
final Constructor<? extends AIConfig> constructor = configClass.getDeclaredConstructor();
config = constructor.newInstance();
} catch (final Exception e) {
throw new RuntimeException("Failed to create AIConfig instance", e);
}
}
/**
* 设置apiKey
*
* @param apiKey apiKey
* @return config
* @since 5.8.38
*/
public synchronized AIConfigBuilder setApiKey(final String apiKey) {View on GitHub (pinned to 8870454b2a)
Solutions
- Use a ModelName enum value: new AIConfigBuilder(ModelName.OLLAMA.getValue()).
- Ensure the target model module is a dependency (it provides the AIConfig SPI registration).
- Configure the shade plugin with ServicesResourceTransformer to merge META-INF/services entries.
- Call AIConfigRegistry.getConfigClass(name) at startup to confirm registration before building.
Example fix
// before
new AIConfigBuilder("gpt-4o"); // -> Unsupported model: gpt-4o
// after
new AIConfigBuilder(ModelName.OPENAI.getValue()).setModel("gpt-4o"); Defensive patterns
Strategy: validation
Validate before calling
// Confirm the config class is registered before building
String vendor = ModelName.OPENAI.getValue();
if (AIConfigRegistry.getConfigClass(vendor) == null) {
throw new IllegalStateException(
"No AIConfig registered for " + vendor + "; check the module dependency / SPI");
}
new AIConfigBuilder(vendor); Try / catch
try {
return new AIConfigBuilder(vendor);
} catch (RuntimeException e) {
Throwable root = e.getCause() != null ? e.getCause() : e;
if (root instanceof IllegalArgumentException
&& root.getMessage().startsWith("Unsupported model")) {
// vendor not registered -> fix classpath / shade SPI
}
throw e;
} Prevention
- Derive the constructor argument from ModelName enum values.
- Verify META-INF/services/cn.hutool.ai.core.AIConfig survives packaging.
- Assert AIConfigRegistry.getConfigClass(vendor) != null at boot.
When it happens
Trigger: Calling new AIConfigBuilder("claude") or any vendor not among hutool/deepSeek/openai/doubao/grok/ollama/gemini; passing the concrete model id instead of the vendor name; the model submodule jar (which carries both the AIConfig SPI entry and the config class) is absent from the classpath.
Common situations: Fat-jar shading that lost META-INF/services/cn.hutool.ai.core.AIConfig; typo in the vendor string; only depending on hutool-ai core without a model module; passing uppercase or mixed-case incorrectly is NOT the cause (lookup is case-insensitive) but a wrong vendor string is.
Related errors
- Unsupported model:
- Failed to create AIConfig instance
- Model service is not of type:
- alphabet must contain at least %d unique characters: %d
- alphabet must not contain spaces: index %d
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/d49d7985e4e2faaf.
Report an issue: GitHub.