alibaba/spring-ai-alibaba · error · RuntimeException
模型配置不存在:
Error message
模型配置不存在:
What it means
ChatClientFactoryDelegate.createChatClient first looks up the model config in a bridging service, then falls back to modelConfigRepository.findById. If both return null, it throws this RuntimeException because a ChatClient cannot be built without a model configuration record for the given id.
Source
Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/service/client/ChatClientFactoryDelegate.java:85
return createChatClient(modelConfigId, userParameters, null,null);
}
public ChatClient createChatClient(Long modelConfigId, Map<String, Object> userParameters, Map<String, String> observationMetadata){
return createChatClient(modelConfigId, userParameters, null, observationMetadata);
}
public ChatClient createChatClient(Long modelConfigId, Map<String, Object> userParameters, List<Advisor> advisors, Map<String, String> observationMetadata) {
// 优先从桥接服务查找(从Manager层查询)
ModelConfigDO config = modelConfigBridgeService.findById(modelConfigId);
// 如果桥接服务中找不到,尝试从ModelConfigRepository查找(保持向后兼容)
if (config == null) {
log.debug("桥接服务中未找到模型配置 id={},尝试从 ModelConfigRepository 查找", modelConfigId);
config = modelConfigRepository.findById(modelConfigId);
}
if (config == null) {
throw new RuntimeException("模型配置不存在: " + modelConfigId);
}
if (config.getStatus() != 1) {
throw new RuntimeException("模型配置已禁用: " + modelConfigId);
}
String provider = config.getProvider().toLowerCase();
log.info("创建模型客户端,提供商: {}, 模型: {}", provider, config.getModelName());
ChatClientFactory factory = chatClientFactories.get(provider);
if (factory == null) {
// 如果找不到对应的 provider factory,默认使用 OpenAI
log.warn("未找到提供商 {} 对应的工厂,使用默认的 OpenAI 工厂", provider);
factory = chatClientFactories.get(OpenAiChatClientFactory.OPEN_AI_PROVIDER);
if (factory == null) {
throw new UnsupportedOperationException("不支持的模型提供商: " + config.getProvider() + ",且默认的 OpenAI 工厂也不可用");
}
}View on GitHub (pinned to f82da0b50f)
Solutions
- Verify the modelConfigId exists: check the models YAML file or the model config store for an entry with that id
- Re-create or re-point the session/request to a valid existing model config id
- Check startup logs for FileModelConfigRepository load failures (apiKey/duplicate id/name validation) that would leave the repository empty
- If configs are managed in the admin UI, confirm the model config was not deleted or disabled by another user
Example fix
// before
chatClientFactoryDelegate.createChatClient(999L, params, metadata); // id never existed
// after
Long id = modelConfigRepository.findByName("qwen-max").getId();
chatClientFactoryDelegate.createChatClient(id, params, metadata); Defensive patterns
Strategy: try-catch
Validate before calling
// Java: check existence before creating the client
if (modelConfigRepository.findById(modelConfigId) == null) {
throw new IllegalStateException("Resolve a valid modelConfigId first: " + modelConfigId);
} Type guard
boolean configExists(ModelConfigDO c) { return c != null; } Try / catch
try {
client = delegate.createChatClient(modelConfigId, params, metadata);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("模型配置不存在")) {
// re-resolve or recreate the model config before retrying
}
} Prevention
- Resolve model ids by name at call time instead of caching raw ids across restarts
- Confirm model config file loaded successfully at startup (watch for validation errors 440-442)
- Log the modelConfigId in requests to speed up stale-id diagnosis
When it happens
Trigger: Calling createChatClient(modelConfigId, ...) with an id that exists neither in the bridge service nor the repository — e.g., a stale modelConfigId from a deleted session, or a config file that failed to load/validate (see errors 440-442).
Common situations: Sessions persisted before the model config was removed; YAML model file edited/renumbered so old ids no longer exist; repository failed to load due to a validation error earlier; case/format mismatch in the id passed by the caller.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/8242e23489c61845.
Report an issue: GitHub.