Mintplex-Labs/anything-llm · error · Error

${e.message}

Error message

${e.message}

What it means

Re-throws the raw rejection message from the OpenAI Responses API (openai.responses.create) call. Unlike the legacy chat completions endpoint, this uses the newer Responses API with input/store/temperature. The catch strips status/cause and surfaces only e.message, so the visible text is whatever the SDK produced (rate limit, invalid model, content policy, context length, auth).

Source

Thrown at server/utils/AiProviders/openAi/index.js:163

    return temperature;
  }

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

    const result = await LLMPerformanceMonitor.measureAsyncFunction(
      this.openai.responses
        .create({
          model: this.model,
          input: messages,
          store: false,
          temperature: this.#temperature(this.model, temperature),
        })
        .catch((e) => {
          throw new Error(e.message);
        })
    );

    if (!result.output.hasOwnProperty("output_text")) return null;

    const usage = result.output.usage || {};
    return {
      textResponse: result.output.output_text,
      metrics: {
        prompt_tokens: usage.input_tokens || 0,
        completion_tokens: usage.output_tokens || 0,
        total_tokens: usage.total_tokens || 0,
        outputTps: usage.output_tokens
          ? usage.output_tokens / result.duration
          : 0,
        duration: result.duration,
        model: this.model,
        provider: this.className,

View on GitHub (pinned to 526360e320)

Solutions

  1. Inspect the full e.message (and ideally e.status/e.error.code from the SDK) to identify the HTTP code.
  2. 429: implement backoff/retry or reduce request frequency.
  3. 401/403: rotate OPEN_AI_KEY to a valid, funded key.
  4. 400 context length: lower prompt size or switch to a larger-window model.

Example fix

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

// after - preserve status so callers can branch on rate-limit vs auth
.catch((e) => {
  const err = new Error(e.message);
  err.status = e.status;
  err.code = e?.error?.code;
  throw err;
})
Defensive patterns

Strategy: retry

Validate before calling

const probeOpenAi = async (openai) => {
  try { await openai.models.retrieve('gpt-4.1-nano'); }
  catch (e) { throw new Error(`OpenAI key/endpoint invalid: ${e.status} ${e.message}`); }
};
await probeOpenAi(openai);

Type guard

const isRateLimited = (e) => e?.status === 429 || e?.error?.code === 'rate_limit_exceeded';
const isAuthError = (e) => e?.status === 401 || e?.status === 403;

Try / catch

try {
  return await llm.getChatCompletion(messages, { temperature });
} catch (e) {
  if (isRateLimited(e)) { await sleep(backoffMs); return retry(); }
  if (isAuthError(e)) throw new Error('OpenAI key invalid or revoked — rotate OPEN_AI_KEY');
  throw e;
}

Prevention

When it happens

Trigger: 429 rate limit / quota; 401 invalid or revoked key (presence is checked but validity is not); 400 context length exceeded or malformed input; 400 content-policy/triggered filter; model id not valid for the Responses API.

Common situations: Quota exhausted mid-session; key revoked after deploy; temperature passed to an o-series model (code already coerces to 1, but custom prefixes can slip); overly large input after context injection; Safety system blocking output.

Related errors


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