{"record":{"id":"ec1b3b44935268b9","repo":"Mintplex-Labs/anything-llm","slug":"perplexity-chat-this-model-is-not-valid-for-ch","errorCode":null,"errorMessage":"Perplexity chat: ${this.model} is not valid for chat completion!","messagePattern":"Perplexity chat: (.+?) is not valid for chat completion!","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/AiProviders/perplexity/index.js","lineNumber":92,"sourceCode":"    return availableModels.hasOwnProperty(model);\n  }\n\n  constructPrompt({\n    systemPrompt = \"\",\n    contextTexts = [],\n    chatHistory = [],\n    userPrompt = \"\",\n  }) {\n    const prompt = {\n      role: \"system\",\n      content: `${systemPrompt}${this.#appendContext(contextTexts)}`,\n    };\n    return [prompt, ...chatHistory, { role: \"user\", content: userPrompt }];\n  }\n\n  async getChatCompletion(messages = null, { temperature = 0.7 }) {\n    if (!(await this.isValidChatCompletionModel(this.model)))\n      throw new Error(\n        `Perplexity chat: ${this.model} is not valid for chat completion!`\n      );\n\n    const result = await LLMPerformanceMonitor.measureAsyncFunction(\n      this.openai.chat.completions\n        .create({\n          model: this.model,\n          messages,\n          temperature,\n        })\n        .catch((e) => {\n          throw new Error(e.message);\n        })\n    );\n\n    if (\n      !result.output.hasOwnProperty(\"choices\") ||\n      result.output.choices.length === 0","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/utils/AiProviders/perplexity/index.js#L74-L110","documentation":"Thrown by PerplexityLLM.getChatCompletion when this.model is not a key returned by allModelInformation() (i.e. it is not present in the bundled ./models.js MODELS map). isValidChatCompletionModel does a strict hasOwnProperty check, so any model id the provider does not recognise is rejected before the network call.","triggerScenarios":"Calling getChatCompletion with a this.model set to something not in the MODELS table — e.g. an offline-only model id, a typo, a model Perplexity has deprecated/renamed, or a custom value passed as modelPreference that the bundled models.js does not list.","commonSituations":"The user passed `modelPreference = \"sonar-medium\"` (old name) after Perplexity renamed to `llama-3-sonar-large-32k-online`; PERPLEXITY_MODEL_PREF in .env points at a model the installed AnythingLLM version predates; copy-pasting an OpenAI model id (\"gpt-4\") into a Perplexity workspace; the bundled models.js was hand-edited and lost entries.","solutions":["Log this.model right before the call and confirm it matches an id in server/utils/AiProviders/perplexity/models.js (e.g. llama-3-sonar-large-32k-online).","If the bundled list is stale, update models.js to include the current Perplexity model ids, or pass a known-good modelPreference explicitly.","Clear PERPLEXITY_MODEL_PREF so the constructor falls back to the hardcoded default (llama-3-sonar-large-32k-online).","Re-select the model in the AnythingLLM UI so a valid id is persisted on the workspace."],"exampleFix":"// before\nconst llm = new PerplexityLLM(embedder, \"sonar-medium-chat\"); // not in MODELS\nawait llm.getChatCompletion(messages, { temperature: 0.7 });\n\n// after\nconst { MODELS } = require(\"./models.js\");\nconst validId = Object.prototype.hasOwnProperty.call(MODELS, \"sonar-medium-chat\")\n  ? \"sonar-medium-chat\"\n  : \"llama-3-sonar-large-32k-online\";\nconst llm = new PerplexityLLM(embedder, validId);\nawait llm.getChatCompletion(messages, { temperature: 0.7 });","handlingStrategy":"validation","validationCode":"const { MODELS } = require(\"./models.js\");\nfunction pickPerplexityModel(pref) {\n  if (pref && Object.prototype.hasOwnProperty.call(MODELS, pref)) return pref;\n  return \"llama-3-sonar-large-32k-online\"; // safe default\n}\nconst model = pickPerplexityModel(process.env.PERPLEXITY_MODEL_PREF);\nconst llm = new PerplexityLLM(embedder, model);\nif (!(await llm.isValidChatCompletionModel(llm.model))) throw new Error(`bad model ${llm.model}`);","typeGuard":"function isKnownPerplexityModel(id, MODELS) {\n  return typeof id === \"string\" && Object.prototype.hasOwnProperty.call(MODELS, id);\n}","tryCatchPattern":"try {\n  await llm.getChatCompletion(messages, { temperature: 0.7 });\n} catch (e) {\n  if (/not valid for chat completion/i.test(e.message)) {\n    llm.model = \"llama-3-sonar-large-32k-online\";\n    return llm.getChatCompletion(messages, { temperature: 0.7 });\n  }\n  throw e;\n}","preventionTips":["Always pass an explicit, known modelPreference instead of relying on env strings users may mistype.","When upgrading AnythingLLM, diff server/utils/AiProviders/perplexity/models.js for renamed ids.","Gate model selection in the UI to the bundled MODELS keys so invalid ids cannot be persisted.","Unit-test isValidChatCompletionModel against the default model id to catch regressions in models.js."],"tags":["validation","model-selection","llm-provider","perplexity","chat-completion"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}