{"record":{"id":"97a2ed7f21c4b2a0","repo":"alibaba/spring-ai-alibaba","slug":"apikey","errorCode":null,"errorMessage":"模型缺少 apiKey","messagePattern":"模型缺少 apiKey","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/repository/impl/FileModelConfigRepository.java","lineNumber":129,"sourceCode":"        return map;\n    }\n    \n    private void validateYamlModel(YamlModel m, Set<Long> ids, Set<String> names) {\n        if (m.id == null) {\n            throw new IllegalArgumentException(\"模型缺少 id\");\n        }\n        if (m.name == null || m.name.isBlank()) {\n            throw new IllegalArgumentException(\"模型缺少 name\");\n        }\n        if (m.provider == null || m.provider.isBlank()) {\n            throw new IllegalArgumentException(\"模型缺少 provider\");\n        }\n        if (m.modelName == null || m.modelName.isBlank()) {\n            throw new IllegalArgumentException(\"模型缺少 modelName\");\n        }\n        //        if (m.baseUrl == null || m.baseUrl.isBlank()) throw new IllegalArgumentException(\"模型缺少 baseUrl\");\n        if (m.apiKey == null || m.apiKey.isBlank()) {\n            throw new IllegalArgumentException(\"模型缺少 apiKey\");\n        }\n        if (!ids.add(m.id)) {\n            throw new IllegalArgumentException(\"重复的模型 id: \" + m.id);\n        }\n        if (!names.add(m.name)) {\n            throw new IllegalArgumentException(\"重复的模型 name: \" + m.name);\n        }\n        if (m.status == null) {\n            m.status = 1;\n        }\n    }\n    \n    private ModelConfigDO toEntity(YamlModel m) {\n        ModelConfigDO.ModelConfigDOBuilder b = ModelConfigDO.builder().id(m.id).name(m.name)\n                .provider(m.provider.toLowerCase()).modelName(m.modelName).baseUrl(m.baseUrl)\n                .apiKey(environment != null ? environment.resolvePlaceholders(m.apiKey) : m.apiKey).status(m.status)\n                .createTime(LocalDateTime.now()).updateTime(LocalDateTime.now());\n        ","sourceCodeStart":111,"sourceCodeEnd":147,"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/repository/impl/FileModelConfigRepository.java#L111-L147","documentation":"FileModelConfigRepository.validateYamlModel validates each model entry loaded from the YAML model-config file. When an entry has a null or blank apiKey, it throws this IllegalArgumentException to abort loading, since most model providers cannot be invoked without credentials. The loadFromFile caller fails fast rather than registering an unusable model.","triggerScenarios":"Calling loadFromFile (at repository startup or file reload) when the YAML models file contains a model entry whose apiKey field is missing, empty (\"\"), or whitespace-only.","commonSituations":"Hand-editing the YAML and omitting apiKey; copying a model entry as a template without filling in the key; environment-specific key injection failing (placeholder left as ${DASHSCOPE_API_KEY} unresolved or blank); sharing sanitized config files with keys stripped.","solutions":["Open the models YAML file loaded by FileModelConfigRepository and set a non-blank apiKey for the offending model entry","If the key comes from an environment variable or config placeholder, verify it is actually set in the runtime environment and resolved at load time","Temporarily comment out or remove the incomplete model entry so the remaining valid models load","Check the exception message chain / file watch logs to identify which model id is missing the key"],"exampleFix":"// before (models.yml)\nmodels:\n  - id: 1\n    name: qwen-max\n    modelName: qwen-max\n    apiKey:\n// after\nmodels:\n  - id: 1\n    name: qwen-max\n    modelName: qwen-max\n    apiKey: sk-xxxxxxxxxxxxxxxx","handlingStrategy":"validation","validationCode":"// Java: check before loading/registering\nif (model.getApiKey() == null || model.getApiKey().isBlank()) {\n    throw new IllegalStateException(\"Skip model \" + model.getName() + \": apiKey missing\");\n}","typeGuard":"boolean hasApiKey(m) { return m != null && m.getApiKey() != null && !m.getApiKey().isBlank(); }","tryCatchPattern":"try {\n    repository.loadFromFile(path);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"apiKey\")) {\n        log.error(\"Model config file has a model without apiKey: {}\", e.getMessage());\n    }\n}","preventionTips":["Keep api keys in environment variables or a secret manager and verify they resolve before startup","Add a CI/startup check that validates all model entries have non-blank apiKey","Never hand out sanitized config templates without placeholder validation"],"tags":["configuration","model-config","api-key","yaml"],"backgroundTag":"missing-api-key","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"}