{"record":{"id":"e57990a0e1721b26","repo":"OtterMind/Chat2DB","slug":"ai-model-config-notfound","errorCode":"ai.model.config.notFound","errorMessage":"ai.model.config.notFound","messagePattern":"ai\\.model\\.config\\.notFound","errorType":"error_code","errorClass":"BusinessException","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":245,"sourceCode":"        return ModelConfigTestResponse.failure(null, null,\n                \"Connection test currently supports OpenAI-compatible models only.\");\n    }\n\n    public synchronized AiRuntimeModel resolveRuntimeModel(AiChatRuntimeResolveRequest request) {\n        Long userId = identityService.currentUserId();\n        AiModelConfig baseConfig = null;\n        boolean systemPreset = false;\n        if (StringUtils.isNotBlank(request.getModelConfigId())) {\n            String modelConfigId = request.getModelConfigId().trim();\n            if (modelConfigId.startsWith(PRESET_VALUE_PREFIX)) {\n                throw new BusinessException(ERROR_MODEL_CONFIG_REQUIRED);\n            } else {\n                String resolvedId = modelConfigId.startsWith(CONFIG_VALUE_PREFIX)\n                        ? modelConfigId.substring(CONFIG_VALUE_PREFIX.length())\n                        : modelConfigId;\n                baseConfig = findById(userConfigMap.getOrDefault(userId, new ArrayList<>()), resolvedId);\n                if (Objects.isNull(baseConfig)) {\n                    throw new BusinessException(\"ai.model.config.notFound\");\n                }\n            }\n        } else if (StringUtils.isNotBlank(request.getProvider()) && StringUtils.isNotBlank(request.getModel())) {\n            baseConfig = new AiModelConfig();\n            baseConfig.setProvider(request.getProvider());\n            baseConfig.setModel(request.getModel());\n            baseConfig.setApiKey(request.getApiKey());\n            baseConfig.setBaseUrl(request.getBaseUrl());\n            baseConfig.setProjectId(request.getProjectId());\n            baseConfig.setLocation(request.getLocation());\n            baseConfig.setTemperature(request.getTemperature());\n            baseConfig.setMaxTokens(request.getMaxTokens());\n            systemPreset = isPresetModel(request.getProvider(), request.getModel())\n                    && StringUtils.isBlank(request.getApiKey())\n                    && StringUtils.isBlank(request.getBaseUrl())\n                    && StringUtils.isBlank(request.getProjectId())\n                    && StringUtils.isBlank(request.getLocation());\n            if (systemPreset) {","sourceCodeStart":227,"sourceCodeEnd":263,"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#L227-L263","documentation":"Thrown by AiModelConfigServiceImpl.resolveRuntimeModel when a modelConfigId was provided (not preset-prefixed) and resolved to an id, but findById returned null against the current user's config list. The referenced config does not exist for this user. The i18n message resolves to 'AI model configuration does not exist.'","triggerScenarios":"modelConfigId (after stripping the optional 'config:' prefix) does not match any AiModelConfig id in userConfigMap for the current identityService user. Caused by a deleted config, a config owned by another user, an id typo, or stale frontend state referencing a removed config.","commonSituations":"User deleted a saved model config then sent a chat request still referencing its id; the id belongs to a different user account; the in-memory userConfigMap is keyed by userId and the caller's identity resolves to a user with no such config; an id mismatch after migration.","solutions":["Refresh the model config list for the current user and use a valid 'config:<id>' (or default-flagged config).","If the config was deleted, create a new one and update the frontend's selected id.","Verify the authenticated user matches the config's userId; configs are user-scoped."],"exampleFix":"// before\nresolve.setModelConfigId(\"config:99\"); // 99 was deleted\n\n// after\nList<AiModelConfig> mine = configService.listMine();\nAiModelConfig active = mine.stream().filter(AiModelConfig::getDefaultConfig).findFirst()\n    .orElseThrow(() -> new IllegalStateException(\"no config\"));\nresolve.setModelConfigId(\"config:\" + active.getId());","handlingStrategy":"validation","validationCode":"List<AiModelConfig> mine = configService.listMine();\nString id = stripConfigPrefix(request.getModelConfigId());\nif (mine.stream().noneMatch(c -> Objects.equals(String.valueOf(c.getId()), id))) {\n    return ResponseEntity.badRequest().body(\"config not found for this user\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    service.resolveRuntimeModel(request);\n} catch (BusinessException e) {\n    if (\"ai.model.config.notFound\".equals(e.getCode())) {\n        return ResponseEntity.status(404).body(\"model config does not exist\");\n    }\n    throw e;\n}","preventionTips":["After deleting a config, clear any cached selected id in the frontend.","Refresh the config list before sending a request that references an id.","Remember configs are user-scoped; do not share ids across users."],"tags":["ai","model-config","not-found","ownership"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}