Mintplex-Labs/anything-llm · error · Error

${e.message}

Error message

${e.message}

What it means

Re-throws the raw rejection message from the OpenRouter OpenAI-compatible chat.completions.create call. OpenRouter is middleware, so rejections often carry upstream-provider context: 404 model not found (server-side, distinct from the local cache check), 402 payment required / no credits, 429 rate limit, 503 upstream provider down. The catch surfaces only e.message.

Source

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

  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);
        })
    );

    if (
      !result?.output?.hasOwnProperty("choices") ||
      result?.output?.choices?.length === 0
    )
      throw new Error(
        `Invalid response body returned from OpenRouter: ${result.output?.error?.message || "Unknown error"} ${result.output?.error?.code || "Unknown code"}`
      );

    return {
      textResponse: this.#parseReasoningFromResponse(result.output.choices[0]),
      metrics: {
        prompt_tokens: result.output.usage.prompt_tokens || 0,
        completion_tokens: result.output.usage.completion_tokens || 0,
        total_tokens: result.output.usage.total_tokens || 0,
        outputTps: result.output.usage.completion_tokens / result.duration,

View on GitHub (pinned to 526360e320)

Solutions

  1. Read e.message and e.status to classify (402 vs 429 vs 503).
  2. 402: top up OpenRouter credits or switch to a free model.
  3. 503/502: retry with backoff or pick a different provider for the same model.
  4. 429: reduce concurrency / add backoff; 404: re-sync the model catalog (see error 276).

Example fix

// before
.catch((e) => { throw new Error(e.message); })

// after - keep status so callers can retry 5xx / back off 429
.catch((e) => {
  const err = new Error(e.message);
  err.status = e.status;
  err.upstream = e?.error?.code;
  throw err;
})
Defensive patterns

Strategy: try-catch

Validate before calling

const ensureOpenRouterCredits = async (apiKey) => {
  const res = await fetch('https://openrouter.ai/api/v1/key', {
    headers: { Authorization: `Bearer ${apiKey}` },
  });
  if (!res.ok) throw new Error(`OpenRouter key check failed: HTTP ${res.status}`);
  const { data } = await res.json();
  if (Number(data?.limit ?? 0) - Number(data?.usage ?? 0) <= 0)
    throw new Error('OpenRouter credit balance exhausted');
};
await ensureOpenRouterCredits(process.env.OPENROUTER_API_KEY);

Type guard

const isRetryableOpenRouter = (e) =>
  e?.status === 429 || e?.status === 502 || e?.status === 503;
const isCreditError = (e) => e?.status === 402;

Try / catch

try {
  return await llm.getChatCompletion(messages, { temperature });
} catch (e) {
  if (isRetryableOpenRouter(e)) { await sleep(backoffMs); return retry(); }
  if (isCreditError(e)) throw new Error('OpenRouter out of credit — top up balance');
  throw e;
}

Prevention

When it happens

Trigger: OpenRouter returns 404 (model id valid in cache but unavailable server-side), 402 (zero credit balance), 429 (rate limited), 503 (upstream provider error/degraded), or a 400 from a malformed request.

Common situations: Free-tier quota exhausted; selected upstream provider is down; credit balance is zero; region-restricted model; rate limit from too many concurrent requests; model id correct in cache but removed server-side since last sync.

Related errors


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