chinabugotech/hutool · error · IllegalArgumentException

Unsupported model:

Error message

Unsupported model: 

What it means

Thrown by AIServiceFactory.getAIService when no AIServiceProvider is registered for config.getModelName(). The factory builds its provider map from Java SPI (ServiceLoaderUtil.load(AIServiceProvider.class)), keyed by provider.getServiceName().toLowerCase(). If that key is absent, the requested vendor is not on the classpath as a registered SPI provider. Valid vendor keys are the ModelName enum values: hutool, deepSeek, openai, doubao, grok, ollama, gemini (matched case-insensitively).

Source

Thrown at hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java:72

	 */
	public static AIService getAIService(final AIConfig config) {
		return getAIService(config, AIService.class);
	}

	/**
	 * 获取AI服务
	 *
	 * @param config AIConfig配置
	 * @param clazz AI服务类
	 * @return clazz对应的AI服务类实例
	 * @since 5.8.38
	 * @param <T> AI服务类
	 */
	@SuppressWarnings("unchecked")
	public static <T extends AIService> T getAIService(final AIConfig config, final Class<T> clazz) {
		final AIServiceProvider provider = providers.get(config.getModelName().toLowerCase());
		if (provider == null) {
			throw new IllegalArgumentException("Unsupported model: " + config.getModelName());
		}

		final AIService service = provider.create(config);
		if (!clazz.isInstance(service)) {
			throw new AIException("Model service is not of type: " + clazz.getSimpleName());
		}

		return (T) service;
	}
}

View on GitHub (pinned to 8870454b2a)

Solutions

  1. Pass the vendor name exactly as defined in ModelName (e.g. ModelName.OPENAI.getValue() -> "openai"), not the model id.
  2. Confirm the model submodule (e.g. hutool-ai model openai classes) is on the runtime classpath.
  3. If using maven-shade-plugin, configure ServicesResourceTransformer so META-INF/services/cn.hutool.ai.core.AIServiceProvider is merged, not overwritten.
  4. In Spring Boot fat jars, verify BOOT-INF/lib contains the module and that the SPI resource survived repackaging.
  5. List providers at startup via ServiceLoader.load(AIServiceProvider.class) to see which names are actually registered.

Example fix

// before
AIConfig cfg = new AIConfigBuilder("gpt-4").setApiKey(k).build();
AIUtil.getAIService(cfg); // -> Unsupported model: gpt-4

// after
AIConfig cfg = new AIConfigBuilder(ModelName.OPENAI.getValue()) // "openai"
    .setApiKey(k)
    .setModel("gpt-4")   // concrete model goes here
    .build();
AIUtil.getOpenAIService(cfg);
Defensive patterns

Strategy: validation

Validate before calling

// Validate vendor name against registered providers BEFORE calling the factory
String vendor = ModelName.OPENAI.getValue(); // prefer enum
java.util.List<String> registered = new java.util.ArrayList<>();
for (AIServiceProvider p : java.util.ServiceLoader.load(AIServiceProvider.class)) {
    registered.add(p.getServiceName().toLowerCase());
}
if (!registered.contains(vendor.toLowerCase())) {
    throw new IllegalStateException(
        "No AIServiceProvider for '" + vendor + "'. Registered: " + registered);
}

Try / catch

try {
    AIService s = AIUtil.getAIService(config);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Unsupported model")) {
        // config.getModelName() not registered -> fix vendor string / classpath / SPI merge
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling AIUtil.getAIService(config) or AIServiceFactory.getAIService(config, clazz) where config.getModelName() returns a string with no matching AIServiceProvider on the classpath. Typical: passing the concrete model id ("gpt-4", "deepseek-chat") instead of the vendor name ("openai", "deepSeek"), or a typo, or the model submodule jar is missing.

Common situations: Shading the app into a fat jar without a ServicesResourceTransformer / ServicesAppendingTransformer (META-INF/services merge lost); depending on hutool-ai but not pulling in the specific model module; passing a custom AIConfig whose getModelName() does not match any registered provider; Spring Boot fat-jar packaging that drops SPI files.

Related errors


AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14). Data as JSON: /api/errors/9a9654b841707b42. Report an issue: GitHub.