HKUDS/DeepTutor · error · LLMConfigError

Model not configured for OpenAI provider

Error message

Model not configured for OpenAI provider

What it means

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.

Source

Thrown at deeptutor/services/llm/providers/open_ai.py:77

        super().__init__(config)
        http_client = None
        if load_system_settings()["disable_ssl_verify"]:
            if os.getenv("ENVIRONMENT", "").lower() in ("prod", "production"):
                raise LLMConfigError("DISABLE_SSL_VERIFY is not allowed in production")
            logger.warning("SSL verification disabled for OpenAI HTTP client")
            http_client = httpx.AsyncClient(verify=False)  # nosec B501
        self.client = openai.AsyncOpenAI(
            api_key=self.api_key,
            base_url=self.base_url or None,
            http_client=http_client,
        )

    @_typed_track_llm_call("openai")
    async def complete(self, prompt: str, **kwargs: object) -> TutorResponse:
        model_raw = kwargs.pop("model", None)
        model = model_raw if isinstance(model_raw, str) and model_raw else self.config.model
        if not model:
            raise LLMConfigError("Model not configured for OpenAI provider")
        kwargs.pop("stream", None)

        requested_max_tokens = (
            kwargs.pop("max_tokens", None)
            or kwargs.pop("max_completion_tokens", None)
            or getattr(self.config, "max_tokens", 4096)
        )
        if isinstance(requested_max_tokens, (int, float, str)):
            max_tokens = int(requested_max_tokens)
        else:
            max_tokens = int(getattr(self.config, "max_tokens", 4096))
        kwargs.update(get_token_limit_kwargs(model, max_tokens))

        async def _call_api() -> TutorResponse:
            request_kwargs: dict[str, object] = dict(kwargs)
            response = await self.client.chat.completions.create(  # type: ignore[call-overload]
                model=model,
                messages=[{"role": "user", "content": prompt}],

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Set model in the LLMConfig used to construct the provider (e.g. 'gpt-4o-mini').
  2. Or pass model=... per call: complete(prompt, model='gpt-4o-mini').
  3. Check the provider/catalog settings for an empty model field.

Example fix

# before
resp = await provider.complete('hi')  # config.model is None
# after
resp = await provider.complete('hi', model='gpt-4o-mini')
Defensive patterns

Strategy: validation

Validate before calling

def openai_complete_ready(config, kwargs: dict) -> bool:
    return bool(kwargs.get('model') or getattr(config, 'model', None))

Try / catch

try:
    resp = await provider.complete(prompt)
except LLMConfigError as e:
    if 'Model not configured' in str(e):
        resp = await provider.complete(prompt, model=DEFAULT_MODEL)
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/368a6b7ebb697955. Report an issue: GitHub.