Mintplex-Labs/anything-llm · error · Error

OpenRouter chat: ${this.model} is not valid for chat complet

Error message

OpenRouter chat: ${this.model} is not valid for chat completion!

What it means

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.

Source

Thrown at server/utils/AiProviders/openRouter/index.js:243

    attachments = [],
  }) {
    const prompt = {
      role: "system",
      content: `${systemPrompt}${this.#appendContext(contextTexts)}`,
    };
    return [
      prompt,
      ...formatChatHistory(chatHistory, this.#generateContent),
      {
        role: "user",
        content: this.#generateContent({ userPrompt, attachments }),
      },
    ];
  }

  async getChatCompletion(messages = null, { temperature = 0.7, user = null }) {
    if (!(await this.isValidChatCompletionModel(this.model)))
      throw new Error(
        `OpenRouter chat: ${this.model} is not valid for chat completion!`
      );

    const result = await LLMPerformanceMonitor.measureAsyncFunction(
      this.openai.chat.completions
        .create({
          model: this.model,
          messages,
          temperature,
          // This is an OpenRouter specific option that allows us to get the reasoning text
          // before the token text.
          include_reasoning: true,
          user: user?.id ? `user_${user.id}` : "",
        })
        .catch((e) => {
          throw new Error(e.message);
        })
    );

View on GitHub (pinned to 526360e320)

Solutions

  1. Delete storage/models/openrouter/models.json and .cached_at to force a fresh catalog fetch, then restart.
  2. Verify the exact id at openrouter.ai/models (copy the full slug).
  3. Use 'openrouter/auto' (the constructor default) as a fallback.
  4. Ensure the server can reach https://openrouter.ai/api/v1/models.

Example fix

// before
async isValidChatCompletionModel(model = '') {
  await this.#syncModels();
  const availableModels = this.models();
  return availableModels.hasOwnProperty(model);
}

// after - force-refresh once if the model is missing, to avoid stale-cache false negatives
async isValidChatCompletionModel(model = '') {
  await this.#syncModels();
  if (this.models().hasOwnProperty(model)) return true;
  await fetchOpenRouterModels(); // one forced refresh
  return this.models().hasOwnProperty(model);
}
Defensive patterns

Strategy: validation

Validate before calling

const isOpenRouterModelKnown = async (model) => {
  const res = await fetch('https://openrouter.ai/api/v1/models');
  const { data = [] } = await res.json();
  return data.some((m) => m.id === model);
};
if (!(await isOpenRouterModelKnown(modelId)))
  throw new Error(`OpenRouter model '${modelId}' not in live catalog.`);

Type guard

const isKnownOpenRouterModel = (model, cache) =>
  typeof model === 'string' && !!cache && Object.prototype.hasOwnProperty.call(cache, model);

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13). Data as JSON: /api/errors/fafb11d832547952. Report an issue: GitHub.