{"record":{"id":"368a6b7ebb697955","repo":"HKUDS/DeepTutor","slug":"model-not-configured-for-openai-provider","errorCode":null,"errorMessage":"Model not configured for OpenAI provider","messagePattern":"Model not configured for OpenAI provider","errorType":"validation","errorClass":"LLMConfigError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/llm/providers/open_ai.py","lineNumber":77,"sourceCode":"        super().__init__(config)\n        http_client = None\n        if load_system_settings()[\"disable_ssl_verify\"]:\n            if os.getenv(\"ENVIRONMENT\", \"\").lower() in (\"prod\", \"production\"):\n                raise LLMConfigError(\"DISABLE_SSL_VERIFY is not allowed in production\")\n            logger.warning(\"SSL verification disabled for OpenAI HTTP client\")\n            http_client = httpx.AsyncClient(verify=False)  # nosec B501\n        self.client = openai.AsyncOpenAI(\n            api_key=self.api_key,\n            base_url=self.base_url or None,\n            http_client=http_client,\n        )\n\n    @_typed_track_llm_call(\"openai\")\n    async def complete(self, prompt: str, **kwargs: object) -> TutorResponse:\n        model_raw = kwargs.pop(\"model\", None)\n        model = model_raw if isinstance(model_raw, str) and model_raw else self.config.model\n        if not model:\n            raise LLMConfigError(\"Model not configured for OpenAI provider\")\n        kwargs.pop(\"stream\", None)\n\n        requested_max_tokens = (\n            kwargs.pop(\"max_tokens\", None)\n            or kwargs.pop(\"max_completion_tokens\", None)\n            or getattr(self.config, \"max_tokens\", 4096)\n        )\n        if isinstance(requested_max_tokens, (int, float, str)):\n            max_tokens = int(requested_max_tokens)\n        else:\n            max_tokens = int(getattr(self.config, \"max_tokens\", 4096))\n        kwargs.update(get_token_limit_kwargs(model, max_tokens))\n\n        async def _call_api() -> TutorResponse:\n            request_kwargs: dict[str, object] = dict(kwargs)\n            response = await self.client.chat.completions.create(  # type: ignore[call-overload]\n                model=model,\n                messages=[{\"role\": \"user\", \"content\": prompt}],","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/llm/providers/open_ai.py#L59-L95","documentation":"complete() needs a model identifier to route the request; if neither the per-call kwargs 'model' nor self.config.model provides one, LLMConfigError is raised before spending an API call.","triggerScenarios":"Calling OpenAIProvider.complete(prompt) with no model kwarg when config.model is None/'' — e.g. a settings entry or LLMConfig built without a model field.","commonSituations":"Default LLMConfig() never populated with a model; catalog entry missing the model name after migrations; code paths that previously defaulted model now hitting the explicit guard.","solutions":["Set model in the LLMConfig used to construct the provider (e.g. 'gpt-4o-mini').","Or pass model=... per call: complete(prompt, model='gpt-4o-mini').","Check the provider/catalog settings for an empty model field."],"exampleFix":"# before\nresp = await provider.complete('hi')  # config.model is None\n# after\nresp = await provider.complete('hi', model='gpt-4o-mini')","handlingStrategy":"validation","validationCode":"def openai_complete_ready(config, kwargs: dict) -> bool:\n    return bool(kwargs.get('model') or getattr(config, 'model', None))","typeGuard":null,"tryCatchPattern":"try:\n    resp = await provider.complete(prompt)\nexcept LLMConfigError as e:\n    if 'Model not configured' in str(e):\n        resp = await provider.complete(prompt, model=DEFAULT_MODEL)\n    else:\n        raise","preventionTips":["Always set config.model when constructing LLMConfig for OpenAI","Validate provider config in startup checks","Prefer explicit per-call model names over relying on defaults"],"tags":["config","openai","missing-model"],"backgroundTag":"missing-required-config","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}