{"record":{"id":"7517ff8bb6234abf","repo":"Mintplex-Labs/anything-llm","slug":"litellm-must-have-a-valid-model-set","errorCode":null,"errorMessage":"LiteLLM must have a valid model set.","messagePattern":"LiteLLM must have a valid model set\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/AiProviders/liteLLM/index.js","lineNumber":26,"sourceCode":"} = require(\"../../helpers/chat/responses\");\n\nclass LiteLLM {\n  constructor(embedder = null, modelPreference = null) {\n    const { OpenAI: OpenAIApi } = require(\"openai\");\n    if (!process.env.LITE_LLM_BASE_PATH)\n      throw new Error(\n        \"LiteLLM must have a valid base path to use for the api.\"\n      );\n\n    this.className = \"LiteLLM\";\n    this.basePath = process.env.LITE_LLM_BASE_PATH;\n    this.openai = new OpenAIApi({\n      baseURL: this.basePath,\n      apiKey: process.env.LITE_LLM_API_KEY ?? null,\n    });\n    this.model = modelPreference ?? process.env.LITE_LLM_MODEL_PREF ?? null;\n\n    if (!this.model) throw new Error(\"LiteLLM must have a valid model set.\");\n    this.limits = {\n      history: this.promptWindowLimit() * 0.15,\n      system: this.promptWindowLimit() * 0.15,\n      user: this.promptWindowLimit() * 0.7,\n    };\n\n    this.embedder = embedder ?? new NativeEmbedder();\n    this.defaultTemp = 0.7;\n    this.log(`Inference API: ${this.basePath} Model: ${this.model}`);\n  }\n\n  log(text, ...args) {\n    console.log(`\\x1b[36m[${this.className}]\\x1b[0m ${text}`, ...args);\n  }\n\n  #appendContext(contextTexts = []) {\n    if (!contextTexts || !contextTexts.length) return \"\";\n    return (","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/utils/AiProviders/liteLLM/index.js#L8-L44","documentation":"LiteLLM class throws when this.model resolves to null: this.model = modelPreference ?? LITE_LLM_MODEL_PREF ?? null. LiteLLM requires an explicit model string because it is a router — the model id (which may be provider-prefixed like 'gpt-4o-mini' or 'ollama/llama3') determines where the proxy forwards the request. Note ?? semantics: an empty-string modelPreference suppresses the env fallback and triggers this throw.","triggerScenarios":"Constructing the class with modelPreference null/undefined (or the literal \"\", due to nullish coalescing) while LITE_LLM_MODEL_PREF is unset — i.e., configuring the base path and API key but never naming a model. The constructor computes this.limits from promptWindowLimit() immediately after, so the provider cannot be built modelless.","commonSituations":"The model var commented out in .env templates; workspace-level model field stored as empty string and passed verbatim; using an old variable name (e.g., LITELLM_MODEL_PREF without the underscore) after an upgrade; expecting the proxy's default model to apply — this client does not have one.","solutions":["Set LITE_LLM_MODEL_PREF to a model the proxy can route, using its exact alias (e.g., LITE_LLM_MODEL_PREF=ollama/llama3 or model-name from litellm config.yaml).","If constructing directly, pass a non-empty second argument and never pass \"\".","Verify the alias exists: curl $LITE_LLM_BASE_PATH/v1/models with the API key.","Restart the server after env edits."],"exampleFix":"# before (.env)\nLITE_LLM_BASE_PATH=http://127.0.0.1:4000\n\n# after (.env)\nLITE_LLM_BASE_PATH=http://127.0.0.1:4000\nLITE_LLM_MODEL_PREF=gpt-4o-mini","handlingStrategy":"validation","validationCode":"// normalize \"\" to null so ?? fallback behaves as intended\nconst liteModel = modelPreference?.trim() || process.env.LITE_LLM_MODEL_PREF || null;\nif (!liteModel) throw new Error(\"LITE_LLM_MODEL_PREF or modelPreference required\");\nconst llm = new LiteLLM(embedder, liteModel);","typeGuard":"function hasLiteModel(arg) {\n  const m = arg ?? process.env.LITE_LLM_MODEL_PREF ?? null;\n  return typeof m === \"string\" && m.trim().length > 0;\n}","tryCatchPattern":"try {\n  new LiteLLM(embedder, pref);\n} catch (e) {\n  if (/valid model set/i.test(e.message)) throw new Error(\"Set LITE_LLM_MODEL_PREF to a model alias the proxy can route\");\n  throw e;\n}","preventionTips":["Remember ?? semantics: empty strings do not fall through — trim and coerce to null first.","Keep model aliases in sync with the LiteLLM proxy's config.yaml; verify via /v1/models.","Include the provider prefix (e.g., ollama/llama3) when the proxy routes by it."],"tags":["litellm","anythingllm","model-selection","env-var","nullish-coalescing","configuration"],"backgroundTag":"model-not-configured","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}