{"record":{"id":"4b1195d8c4d28516","repo":"Mintplex-Labs/anything-llm","slug":"apipie-chat-this-model-is-not-valid-for-chat-c","errorCode":null,"errorMessage":"ApiPie chat: ${this.model} is not valid for chat completion!","messagePattern":"ApiPie chat: (.+?) is not valid for chat completion!","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/AiProviders/apipie/index.js","lineNumber":192,"sourceCode":"    attachments = [],\n  }) {\n    const prompt = {\n      role: \"system\",\n      content: `${systemPrompt}${this.#appendContext(contextTexts)}`,\n    };\n    return [\n      prompt,\n      ...formatChatHistory(chatHistory, this.#generateContent),\n      {\n        role: \"user\",\n        content: this.#generateContent({ userPrompt, attachments }),\n      },\n    ];\n  }\n\n  async getChatCompletion(messages = null, { temperature = 0.7 }) {\n    if (!(await this.isValidChatCompletionModel(this.model)))\n      throw new Error(\n        `ApiPie 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":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/utils/AiProviders/apipie/index.js#L174-L210","documentation":"getChatCompletion first calls isValidChatCompletionModel(this.model), which compares the configured model id against the model list ApiPie returns for your key; a mismatch throws this. ApiPie is an aggregator and model ids are namespaced (e.g. \"openrouter/mistral-7b-instruct\"), so bare names, typos, retired ids, and keys without upstream access all fail this preflight.","triggerScenarios":"The default \"openrouter/mistral-7b-instruct\" removed from ApiPie's catalog; a user-entered APIPIE_LLM_MODEL_PREF without the provider prefix; the key lacking access to the upstream provider; a model id copied from a different provider's docs.","commonSituations":"Aggregator catalogs churning as upstream models are added or removed; switching keys with different entitlements; stale saved preferences after long idle periods.","solutions":["Re-fetch the model list in the ApiPie provider settings and pick a currently listed id","Use the fully-qualified namespace/model id exactly as ApiPie lists it","Confirm the key has access to that upstream provider","Clear any stale APIPIE_LLM_MODEL_PREF env override after catalog changes"],"exampleFix":"# before\nexport APIPIE_LLM_MODEL_PREF=mistral-7b-instruct\n\n# after - exact id from ApiPie's /v1/models\nexport APIPIE_LLM_MODEL_PREF=openrouter/mistral-7b-instruct","handlingStrategy":"validation","validationCode":"const models = await apipie.openai.models.list();\nconst ids = models.data.map((m) => m.id);\nif (!ids.includes(modelPref)) {\n  return res.status(400).json({ error: `Model ${modelPref} unavailable. Pick one of: ${ids.slice(0, 20).join(\", \")}...` });\n}","typeGuard":null,"tryCatchPattern":"try {\n  await apipie.getChatCompletion(messages);\n} catch (e) {\n  if (/not valid for chat completion/i.test(e.message)) {\n    // refresh the model list and repick before retrying once\n  }\n  throw e;\n}","preventionTips":["Select models from the provider's live list, never free-typed ids","Copy namespaced ids exactly (provider/model)","Re-validate saved preferences after changing API keys"],"tags":["apipie","model","validation","chat-completion"],"backgroundTag":"invalid-model-name","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"}