{"record":{"id":"ea90d63f8cdaffb2","repo":"assafelovic/gpt-researcher","slug":"model-cannot-be-none","errorCode":null,"errorMessage":"Model cannot be None","messagePattern":"Model cannot be None","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"gpt_researcher/utils/llm.py","lineNumber":72,"sourceCode":"    \"\"\"Create a chat completion using the OpenAI API\n    Args:\n        messages (list[dict[str, str]]): The messages to send to the chat completion.\n        model (str, optional): The model to use. Defaults to None.\n        temperature (float, optional): The temperature to use. Defaults to 0.4.\n        max_tokens (int, optional): The max tokens to use. Defaults to 4000.\n        llm_provider (str, optional): The LLM Provider to use.\n        stream (bool): Whether to stream the response. Defaults to False.\n        webocket (WebSocket): The websocket used in the currect request,\n        llm_kwargs (dict[str, Any], optional): Additional LLM keyword arguments. Defaults to None.\n        cost_callback: Callback function for updating cost.\n        reasoning_effort (str, optional): Reasoning effort for OpenAI's reasoning models. Defaults to 'low'.\n        **kwargs: Additional keyword arguments.\n    Returns:\n        str: The response from the chat completion.\n    \"\"\"\n    # validate input\n    if model is None:\n        raise ValueError(\"Model cannot be None\")\n    # Sanity guard against absurd values (e.g., env var typos). The actual\n    # per-model output limits are enforced by the upstream provider.\n    if max_tokens is not None and max_tokens > 200_000:\n        raise ValueError(\n            f\"max_tokens={max_tokens} exceeds the largest output limit of \"\n            \"any currently available model (128k as of late 2025). \"\n            \"Check your FAST_TOKEN_LIMIT / SMART_TOKEN_LIMIT / \"\n            \"STRATEGIC_TOKEN_LIMIT env vars for typos.\"\n        )\n\n    # Get the provider from supported providers\n    provider_kwargs = {'model': model}\n\n    if llm_kwargs:\n        provider_kwargs.update(llm_kwargs)\n    elif os.environ.get(\"LLM_KWARGS\"):\n        import json\n        try:","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/assafelovic/gpt-researcher/blob/6f998577d547b1e54ec662dac63583aa11e3b84b/gpt_researcher/utils/llm.py#L54-L90","documentation":"create_chat_completion validates its inputs and raises ValueError when the model argument is None. This is a guard against misconfiguration: the LLM layer must know which model to call, and passing None usually means a config key (FAST_LLM/SMART_LLM/STRATEGIC_LLM) was never resolved from settings or env vars.","triggerScenarios":"Calling create_chat_completion(..., model=None), typically because cfg.fast_llm_model / smart_llm / strategic returned None — e.g. a custom Config subclass that didn't populate llm settings, or a direct call where the model param was omitted/misnamed.","commonSituations":"Building a custom Config object and forgetting to set the LLM provider/model fields; upgrading gpt-researcher where config attribute names changed; passing kwargs like model_name= instead of model=.","solutions":["Set the model explicitly in config: FAST_LLM, SMART_LLM, STRATEGIC_LLM (and LLM_PROVIDER) env vars or Config attributes","If calling directly, pass a concrete model string: create_chat_completion(..., model='gpt-4o-mini')","Inspect your Config instance right before the call: print(cfg.fast_llm_model, cfg.smart_llm_model, cfg.strategic_llm_model)","When subclassing Config, ensure you don't shadow llm attributes with None defaults"],"exampleFix":"# before\nresponse = await create_chat_completion(prompt, None)  # ValueError: Model cannot be None\n\n# after\nresponse = await create_chat_completion(prompt, cfg.fast_llm_model or 'gpt-4o-mini')","handlingStrategy":"type-guard","validationCode":"model = cfg.fast_llm_model or cfg.smart_llm_model\nassert model, 'LLM model is unset — check FAST_LLM/SMART_LLM config'","typeGuard":"def has_model(model) -> bool:\n    return isinstance(model, str) and bool(model.strip())","tryCatchPattern":"try:\n    resp = await create_chat_completion(prompt, model)\nexcept ValueError as e:\n    if 'Model cannot be None' in str(e):\n        resp = await create_chat_completion(prompt, 'gpt-4o-mini')\n    else:\n        raise","preventionTips":["Always pass cfg.fast_llm_model / smart_llm_model rather than constructing model strings ad hoc","Unit-test that your Config resolves non-None LLM models before running research","Fail fast at app startup by asserting all *_LLM config values are non-empty strings"],"tags":["validation","llm","config","invalid-argument"],"backgroundTag":"required-argument-none","analyzedSha":"6f998577d547b1e54ec662dac63583aa11e3b84b","analyzedAt":"2026-08-28T17:50:07.383Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}