{"record":{"id":"b2d415878e29e8ae","repo":"alibaba/spring-ai-alibaba","slug":"provider-credential","errorCode":null,"errorMessage":"Provider的credential不存在: {}","messagePattern":"Provider的credential不存在: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/service/impl/ModelConfigBridgeServiceImpl.java","lineNumber":223,"sourceCode":"    /**\n     * 将ModelEntity转换为ModelConfigDO\n     */\n    private ModelConfigDO convertToModelConfigDO(ModelEntity modelEntity) {\n        if (modelEntity == null) {\n            return null;\n        }\n\n        try {\n            // 获取Provider的credential（包含apiKey和endpoint）\n            ProviderConfigInfo providerDetail = providerManager.getProviderDetail(modelEntity.getProvider(), false);\n            if (providerDetail == null) {\n                log.warn(\"Provider不存在: {}\", modelEntity.getProvider());\n                return null;\n            }\n\n            ModelCredential credential = providerDetail.getCredential();\n            if (credential == null) {\n                log.warn(\"Provider的credential不存在: {}\", modelEntity.getProvider());\n                return null;\n            }\n\n            // 解密apiKey\n            String apiKey = credential.getApiKey();\n            if (StringUtils.isNotBlank(apiKey)) {\n                try {\n                    apiKey = RSACryptUtils.decrypt(apiKey);\n                } catch (Exception e) {\n                    log.warn(\"解密apiKey失败，使用原始值: {}\", e.getMessage());\n                }\n            }\n\n            // 获取baseUrl，从credential的endpoint获取\n            String baseUrl = credential.getEndpoint();\n            if (StringUtils.isNotBlank(baseUrl)) {\n                // 移除/v1后缀（如果存在），因为Spring AI会自动添加\n                if (baseUrl.endsWith(\"/v1\") || baseUrl.endsWith(\"/v1/\")) {","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/service/impl/ModelConfigBridgeServiceImpl.java#L205-L241","documentation":"convertToModelConfigDO found the provider via providerManager.getProviderDetail but the ProviderConfigInfo carries no ModelCredential, so no apiKey/endpoint can be attached to the resulting ModelConfigDO; it logs this warning and returns null. The provider exists but is unauthenticated/incomplete.","triggerScenarios":"Provider detail exists but getCredential() returns null — i.e., no API key/credential record has ever been saved for that provider.","commonSituations":"Freshly installed admin where the provider was configured structurally but its API key was never entered; credential was deleted; multi-workspace setup where the credential belongs to another workspace.","solutions":["Save an API key credential for the provider in the model management UI so getCredential() returns a ModelCredential","Verify the credential storage/backend (where ModelCredential records persist) is reachable and populated","If credential is intentionally optional, change call sites to tolerate the null return instead of failing","Re-check workspace/tenant scoping — the credential may exist under a different workspace"],"exampleFix":"// before\nModelConfigDO config = bridgeService.findById(id);\nclient.chat(config); // config is null\n// after\nModelConfigDO config = bridgeService.findById(id);\nif (config == null) { configureProviderCredential(provider); return; }","handlingStrategy":"validation","validationCode":"if (providerManager.getProviderDetail(provider, false).getCredential() == null) { promptForApiKey(provider); }","typeGuard":null,"tryCatchPattern":"ModelConfigDO c = bridge.findById(id); if (c == null) { configureCredential(provider); }","preventionTips":["Enter API keys via the UI on provider setup","Check credential store population after migrations","Scope credentials to the correct workspace"],"tags":["credentials","api-key","missing-credentials"],"backgroundTag":"missing-credentials","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}