{"record":{"id":"fafb11d832547952","repo":"Mintplex-Labs/anything-llm","slug":"openrouter-chat-this-model-is-not-valid-for-ch","errorCode":null,"errorMessage":"OpenRouter chat: ${this.model} is not valid for chat completion!","messagePattern":"OpenRouter chat: (.+?) is not valid for chat completion!","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/AiProviders/openRouter/index.js","lineNumber":243,"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, user = null }) {\n    if (!(await this.isValidChatCompletionModel(this.model)))\n      throw new Error(\n        `OpenRouter 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          // This is an OpenRouter specific option that allows us to get the reasoning text\n          // before the token text.\n          include_reasoning: true,\n          user: user?.id ? `user_${user.id}` : \"\",\n        })\n        .catch((e) => {\n          throw new Error(e.message);\n        })\n    );","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/utils/AiProviders/openRouter/index.js#L225-L261","documentation":"Pre-flight model validation in getChatCompletion. isValidChatCompletionModel calls #syncModels (refetches the public OpenRouter /models catalog only if the local cache is missing or older than 1 week) then checks availableModels.hasOwnProperty(model). The cache lives at storage/models/openrouter/models.json. This throws when the model id is absent from that cached catalog.","triggerScenarios":"Model id typo; model removed from the OpenRouter catalog; corrupt/empty cache file because fetchOpenRouterModels failed at startup; cache older than the model's addition but #syncModels deemed it fresh; user typed a custom id not in the catalog.","commonSituations":"Free model deprecated/renamed; provider slug changed (e.g. anthropic/claude-... id shifted); offline at first boot left an empty models.json; cache written but stale within the 1-week window.","solutions":["Delete storage/models/openrouter/models.json and .cached_at to force a fresh catalog fetch, then restart.","Verify the exact id at openrouter.ai/models (copy the full slug).","Use 'openrouter/auto' (the constructor default) as a fallback.","Ensure the server can reach https://openrouter.ai/api/v1/models."],"exampleFix":"// before\nasync isValidChatCompletionModel(model = '') {\n  await this.#syncModels();\n  const availableModels = this.models();\n  return availableModels.hasOwnProperty(model);\n}\n\n// after - force-refresh once if the model is missing, to avoid stale-cache false negatives\nasync isValidChatCompletionModel(model = '') {\n  await this.#syncModels();\n  if (this.models().hasOwnProperty(model)) return true;\n  await fetchOpenRouterModels(); // one forced refresh\n  return this.models().hasOwnProperty(model);\n}","handlingStrategy":"validation","validationCode":"const isOpenRouterModelKnown = async (model) => {\n  const res = await fetch('https://openrouter.ai/api/v1/models');\n  const { data = [] } = await res.json();\n  return data.some((m) => m.id === model);\n};\nif (!(await isOpenRouterModelKnown(modelId)))\n  throw new Error(`OpenRouter model '${modelId}' not in live catalog.`);","typeGuard":"const isKnownOpenRouterModel = (model, cache) =>\n  typeof model === 'string' && !!cache && Object.prototype.hasOwnProperty.call(cache, model);","tryCatchPattern":null,"preventionTips":["Force-refresh storage/models/openrouter/models.json when a new model is selected.","Copy the exact slug from openrouter.ai/models.","Default to 'openrouter/auto' so a missing specific id does not block chat."],"tags":["openrouter","configuration","validation","cache"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}