{"record":{"id":"8ab6312ac794389b","repo":"Mintplex-Labs/anything-llm","slug":"genericopenai-must-have-a-valid-model-set","errorCode":null,"errorMessage":"GenericOpenAI must have a valid model set.","messagePattern":"GenericOpenAI must have a valid model set\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/AiProviders/genericOpenAi/index.js","lineNumber":41,"sourceCode":"      );\n\n    this.className = \"GenericOpenAiLLM\";\n    this.basePath = process.env.GENERIC_OPEN_AI_BASE_PATH;\n    this.openai = new OpenAIApi({\n      baseURL: this.basePath,\n      apiKey: process.env.GENERIC_OPEN_AI_API_KEY ?? null,\n      defaultHeaders: {\n        \"User-Agent\": getAnythingLLMUserAgent(),\n        ...GenericOpenAiLLM.parseCustomHeaders(),\n      },\n    });\n    this.model =\n      modelPreference ?? process.env.GENERIC_OPEN_AI_MODEL_PREF ?? null;\n    this.maxTokens = process.env.GENERIC_OPEN_AI_MAX_TOKENS\n      ? toValidNumber(process.env.GENERIC_OPEN_AI_MAX_TOKENS, 1024)\n      : 1024;\n    if (!this.model)\n      throw new Error(\"GenericOpenAI 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  /**\n   * Parses custom headers from a CSV-formatted environment variable.\n   * Format: \"Header-Name:value,Another-Header:value2\"","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/utils/AiProviders/genericOpenAi/index.js#L23-L59","documentation":"GenericOpenAiLLM throws after construction when this.model resolves to null — modelPreference was null/undefined AND GENERIC_OPEN_AI_MODEL_PREF is unset. Unlike the base path (checked first), the model is optional in construction order: limits are computed and only then is the missing model rejected. The generic provider cannot discover a default model, so it hard-requires one.","triggerScenarios":"GENERIC_OPEN_AI_BASE_PATH is set but neither the workspace modelPreference nor GENERIC_OPEN_AI_MODEL_PREF is provided. Note modelPreference is read with ?? here, so an explicit empty string from the caller also yields '' which is falsy... in fact '' ?? only skips null/undefined, so '' passes through and still throws via !this.model.","commonSituations":"Configured the generic endpoint but never picked a model in the workspace; UI submitted the model field empty; env var misspelled (GENERIC_OPENAI_MODEL_PREF vs GENERIC_OPEN_AI_MODEL_PREF); server restarted with a trimmed .env.","solutions":["Set GENERIC_OPEN_AI_MODEL_PREF to a model your endpoint serves (check its /models list) and restart","Or select the model explicitly in the workspace chat settings so modelPreference is non-empty","Verify with curl <base_path>/models that the id you set actually exists on the endpoint"],"exampleFix":"# before (.env)\nGENERIC_OPEN_AI_BASE_PATH=http://localhost:1234/v1\n# model unset -> throws at chat time\n\n# after (.env)\nGENERIC_OPEN_AI_BASE_PATH=http://localhost:1234/v1\nGENERIC_OPEN_AI_MODEL_PREF=local-model","handlingStrategy":"validation","validationCode":"const model = modelPreference ?? process.env.GENERIC_OPEN_AI_MODEL_PREF;\nif (!model) {\n  return respond(\"Select a model for the Generic OpenAI endpoint.\");\n}\nconst llm = new GenericOpenAiLLM(embedder, model);","typeGuard":null,"tryCatchPattern":"try {\n  const llm = new GenericOpenAiLLM(embedder, modelPref);\n} catch (err) {\n  if (/must have a valid model set/.test(err.message)) {\n    return respond(\"No model configured — set GENERIC_OPEN_AI_MODEL_PREF or pick one.\");\n  }\n  throw err;\n}","preventionTips":["Fetch the endpoint's /models list and make the user pick from it when saving settings","Never persist empty-string model preferences — treat them as unset","Smoke-test one completion right after configuring the provider"],"tags":["generic-openai","missing-model-configuration","model-config"],"backgroundTag":"missing-model-configuration","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"}