{"record":{"id":"4c8f0e6be583c056","repo":"OtterMind/Chat2DB","slug":"unsupported-provider","errorCode":null,"errorMessage":"Unsupported provider: ","messagePattern":"Unsupported provider: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/ai/AiModelConfigServiceImpl.java","lineNumber":365,"sourceCode":"            return;\n        }\n        if (provider == AiProviderEnum.GEMINI) {\n            runtimeModel.setProjectId(defaultValue(trimToNull(runtimeModel.getProjectId()), trimToNull(System.getenv(\"GOOGLE_CLOUD_PROJECT\"))));\n            runtimeModel.setLocation(defaultValue(trimToNull(runtimeModel.getLocation()), trimToNull(System.getenv(\"GOOGLE_CLOUD_LOCATION\"))));\n            runtimeModel.setLocation(defaultValue(runtimeModel.getLocation(), DEFAULT_GEMINI_LOCATION));\n        }\n    }\n\n    private void validateRuntimeModel(AiRuntimeModel runtimeModel) {\n        if (Objects.isNull(runtimeModel.getProvider())) {\n            throw new IllegalArgumentException(\"provider is required\");\n        }\n        if (StringUtils.isBlank(runtimeModel.getModel())) {\n            throw new IllegalArgumentException(\"model is required\");\n        }\n        AiProviderEnum provider = AiProviderEnum.from(runtimeModel.getProvider());\n        if (provider == null) {\n            throw new IllegalArgumentException(\"Unsupported provider: \" + runtimeModel.getProvider());\n        }\n        if (provider == AiProviderEnum.OPENAI || provider == AiProviderEnum.CLAUDE) {\n            return;\n        }\n        if (provider == AiProviderEnum.GEMINI) {\n        }\n    }\n\n\n    private synchronized void loadFromDisk() {\n        if (!Files.exists(storagePath)) {\n            return;\n        }\n        try {\n            StorageData data = objectMapper.readValue(storagePath.toFile(), StorageData.class);\n            Map<Long, List<AiModelConfig>> loadedConfigMap = new HashMap<>();\n            if (CollectionUtils.isNotEmpty(data.getConfigs())) {\n                data.getConfigs().forEach(config -> {","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/ai/AiModelConfigServiceImpl.java#L347-L383","documentation":"Thrown as IllegalArgumentException('Unsupported provider: ' + runtimeModel.getProvider()) by validateRuntimeModel when AiProviderEnum.from(provider) returns null. from() uppercases and trims, returning null for empty/unknown values; the only accepted providers are OPENAI, CLAUDE, GEMINI, MINIMAX. The provider passed validation as non-null but is not a recognized enum constant.","triggerScenarios":"runtimeModel.getProvider() is a non-null, non-blank string that does not match any AiProviderEnum constant after trim+uppercase: e.g. 'AZURE', 'OPENROUTER', 'ollama', 'mistral', or a typo like 'OPENAI ' is fine (trimmed) but 'OPEN_AI' fails.","commonSituations":"User typed a custom provider string not in the enum; a config imported from another tool carries an unsupported provider; a new provider was added to the UI list without adding it to AiProviderEnum; casing/whitespace variants are tolerated but synonyms are not.","solutions":["Use one of the supported provider constants exactly: OPENAI, CLAUDE, GEMINI, or MINIMAX (case/whitespace insensitive).","For OpenAI-compatible self-hosted endpoints, use provider OPENAI with a custom baseUrl rather than a custom provider string.","If you genuinely need a new provider, add it to AiProviderEnum and implement its applyProviderDefaults branch."],"exampleFix":"// before\nresolve.setProvider(\"ollama\"); // not in enum\n\n// after - use OPENAI provider with a local base url for ollama-style endpoints\nresolve.setProvider(\"OPENAI\");\nresolve.setBaseUrl(\"http://127.0.0.1:11434/v1\");\nresolve.setModel(\"llama3\");\nresolve.setApiKey(\"ollama\"); // placeholder required by client","handlingStrategy":"type-guard","validationCode":"String provider = runtimeModel.getProvider();\nAiProviderEnum p = AiProviderEnum.from(provider);\nif (p == null) {\n    return ResponseEntity.badRequest()\n        .body(\"unsupported provider '\" + provider + \"'; use OPENAI/CLAUDE/GEMINI/MINIMAX\");\n}","typeGuard":"static boolean isSupportedProvider(String provider) {\n    return AiProviderEnum.from(provider) != null;\n}","tryCatchPattern":"try {\n    service.validateRuntimeModel(m);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unsupported provider:\")) {\n        return ResponseEntity.badRequest().body(e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Constrain the provider UI field to OPENAI/CLAUDE/GEMINI/MINIMAX.","For OpenAI-compatible self-hosted endpoints, use OPENAI with a custom baseUrl.","When adding a provider, update AiProviderEnum and its applyProviderDefaults branch together."],"tags":["ai","model-config","provider","enum","validation"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}