{"record":{"id":"675907fafeecc13b","repo":"HKUDS/DeepTutor","slug":"model-is-required-for-cloud-llm-provider","errorCode":null,"errorMessage":"Model is required for cloud LLM provider","messagePattern":"Model is required for cloud LLM provider","errorType":"error_code","errorClass":"LLMConfigError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/llm/cloud_provider.py","lineNumber":179,"sourceCode":"\n    Supports OpenAI-compatible APIs and Anthropic.\n\n    Args:\n        prompt: The user prompt\n        system_prompt: System prompt for context\n        model: Model name\n        api_key: API key\n        base_url: Base URL for the API\n        api_version: API version for Azure OpenAI\n        binding: Provider binding type (openai, anthropic)\n        **kwargs: Additional parameters (temperature, max_tokens, etc.)\n\n    Returns:\n        str: The LLM response\n    \"\"\"\n    binding_lower = (binding or \"openai\").lower()\n    if model is None or not model.strip():\n        raise LLMConfigError(\"Model is required for cloud LLM provider\")\n\n    if binding_lower in [\"anthropic\", \"claude\"]:\n        max_tokens_value = _coerce_int(kwargs.get(\"max_tokens\"), None)\n        temperature_value = _coerce_float(kwargs.get(\"temperature\"), 0.7)\n        return await _anthropic_complete(\n            model=model,\n            prompt=prompt,\n            system_prompt=system_prompt,\n            api_key=api_key,\n            base_url=base_url,\n            max_tokens=max_tokens_value,\n            temperature=temperature_value,\n        )\n\n    if binding_lower == \"cohere\":\n        max_tokens_value = _coerce_int(kwargs.get(\"max_tokens\"), None)\n        temperature_value = _coerce_float(kwargs.get(\"temperature\"), 0.7)\n        return await _cohere_complete(","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/llm/cloud_provider.py#L161-L197","documentation":"The cloud provider's non-streaming complete() entry point dispatches to a binding-specific backend (openai/anthropic/cohere), and every backend needs a model identifier to build the request payload. A blank or None model is rejected with LLMConfigError before any network call. The binding defaults to openai when omitted, but the model has no default.","triggerScenarios":"Calling complete(prompt=..., model=None) or model='  ' via the SDK/CLI; the active runtime profile has no model set so config resolution passes an empty string; a caller reads model from a settings key that does not exist and passes None.","commonSituations":"Fresh install where no model was selected in Settings > Catalog; profile JSON manually edited and model field deleted; code upgraded and the model kwarg was renamed but an old call site still passes model=None.","solutions":["Set an active model in Settings > Catalog (or the equivalent settings JSON) so resolution supplies one.","Pass an explicit model string at the call site: await complete(prompt, model='gpt-4o-mini').","If model comes from config, validate it before calling: if not (model or '').strip(): raise with a specific message.","Check that resolve_llm_runtime_config().model is non-empty when building profiles programmatically."],"exampleFix":"// before\nresp = await llm.complete(prompt=user_text, model=settings.get(\"model\"))\n\n# after\nmodel = (settings.get(\"model\") or \"\").strip()\nif not model:\n    raise ValueError(\"No model configured in settings\")\nresp = await llm.complete(prompt=user_text, model=model)","handlingStrategy":"validation","validationCode":"model = (model or \"\").strip()\nif not model:\n    raise ValueError(\"A model name is required for cloud completion\")\nresp = await complete(prompt=p, model=model)","typeGuard":"def has_model(model: str | None) -> bool:\n    return isinstance(model, str) and bool(model.strip())","tryCatchPattern":"try:\n    resp = await complete(prompt=p, model=model)\nexcept LLMConfigError as e:\n    if \"Model is required\" in str(e):\n        # prompt user to pick a model in Settings > Catalog\n        ...\n    raise","preventionTips":["Select a default model in Settings > Catalog on first run.","Assert resolved.model is non-empty when building profiles programmatically.","Centralize model resolution in one helper so call sites cannot forget it."],"tags":["llm","configuration","model-required","validation"],"backgroundTag":"missing-configuration-value","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}