{"record":{"id":"e86579c354ac3be0","repo":"Mintplex-Labs/anything-llm","slug":"e-message-e86579","errorCode":null,"errorMessage":"${e.message}","messagePattern":"\\$\\{e\\.message\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/AiProviders/openAi/index.js","lineNumber":163,"sourceCode":"    return temperature;\n  }\n\n  async getChatCompletion(messages = null, { temperature = 0.7 }) {\n    if (!(await this.isValidChatCompletionModel(this.model)))\n      throw new Error(\n        `OpenAI chat: ${this.model} is not valid for chat completion!`\n      );\n\n    const result = await LLMPerformanceMonitor.measureAsyncFunction(\n      this.openai.responses\n        .create({\n          model: this.model,\n          input: messages,\n          store: false,\n          temperature: this.#temperature(this.model, temperature),\n        })\n        .catch((e) => {\n          throw new Error(e.message);\n        })\n    );\n\n    if (!result.output.hasOwnProperty(\"output_text\")) return null;\n\n    const usage = result.output.usage || {};\n    return {\n      textResponse: result.output.output_text,\n      metrics: {\n        prompt_tokens: usage.input_tokens || 0,\n        completion_tokens: usage.output_tokens || 0,\n        total_tokens: usage.total_tokens || 0,\n        outputTps: usage.output_tokens\n          ? usage.output_tokens / result.duration\n          : 0,\n        duration: result.duration,\n        model: this.model,\n        provider: this.className,","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/utils/AiProviders/openAi/index.js#L145-L181","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the full e.message (and ideally e.status/e.error.code from the SDK) to identify the HTTP code.","429: implement backoff/retry or reduce request frequency.","401/403: rotate OPEN_AI_KEY to a valid, funded key.","400 context length: lower prompt size or switch to a larger-window model."],"exampleFix":"// before\n.catch((e) => { throw new Error(e.message); })\n\n// after - preserve status so callers can branch on rate-limit vs auth\n.catch((e) => {\n  const err = new Error(e.message);\n  err.status = e.status;\n  err.code = e?.error?.code;\n  throw err;\n})","handlingStrategy":"retry","validationCode":"const probeOpenAi = async (openai) => {\n  try { await openai.models.retrieve('gpt-4.1-nano'); }\n  catch (e) { throw new Error(`OpenAI key/endpoint invalid: ${e.status} ${e.message}`); }\n};\nawait probeOpenAi(openai);","typeGuard":"const isRateLimited = (e) => e?.status === 429 || e?.error?.code === 'rate_limit_exceeded';\nconst isAuthError = (e) => e?.status === 401 || e?.status === 403;","tryCatchPattern":"try {\n  return await llm.getChatCompletion(messages, { temperature });\n} catch (e) {\n  if (isRateLimited(e)) { await sleep(backoffMs); return retry(); }\n  if (isAuthError(e)) throw new Error('OpenAI key invalid or revoked — rotate OPEN_AI_KEY');\n  throw e;\n}","preventionTips":["Branch on e.status to separate retryable (429/5xx) from fatal (401/400) errors.","Keep prompts within the model's context window to avoid 400 length errors.","Monitor quota/billing so the key does not get rate-limited or suspended."],"tags":["openai","llm-provider","runtime","api-error"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}