{"record":{"id":"df2a4308dc0ed6a7","repo":"Mintplex-Labs/anything-llm","slug":"e-message-df2a43","errorCode":null,"errorMessage":"e.message","messagePattern":"e\\.message","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/AiProviders/giteeai/index.js","lineNumber":131,"sourceCode":"    let textResponse = message?.content;\n    if (\n      !!message?.reasoning_content &&\n      message.reasoning_content.trim().length > 0\n    )\n      textResponse = `<think>${message.reasoning_content}</think>${textResponse}`;\n    return textResponse;\n  }\n\n  async getChatCompletion(messages = null, { temperature = 0.7 }) {\n    const result = await LLMPerformanceMonitor.measureAsyncFunction(\n      this.openai.chat.completions\n        .create({\n          model: this.model,\n          messages,\n          temperature,\n        })\n        .catch((e) => {\n          throw new Error(e.message);\n        })\n    );\n\n    if (\n      !result?.output?.hasOwnProperty(\"choices\") ||\n      result?.output?.choices?.length === 0\n    )\n      throw new Error(\n        `Invalid response body returned from GiteeAI: ${JSON.stringify(result.output)}`\n      );\n\n    return {\n      textResponse: this.#parseReasoningFromResponse(result.output.choices[0]),\n      metrics: {\n        prompt_tokens: result.output.usage.prompt_tokens || 0,\n        completion_tokens: result.output.usage.completion_tokens || 0,\n        total_tokens: result.output.usage.total_tokens || 0,\n        outputTps: result.output.usage.completion_tokens / result.duration,","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/utils/AiProviders/giteeai/index.js#L113-L149","documentation":"GiteeAILLM.getChatCompletion rethrows e.message from the OpenAI SDK call to https://ai.gitee.com/v1. It is a passthrough of Gitee AI's HTTP errors: 401 invalid token, 404 unknown model id (this.model defaults to '' when no pref is set, guaranteeing a bad request), 429 rate limits, or network failures to the Gitee endpoint.","triggerScenarios":"Chat request where this.model is '' (no GITEE_AI_MODEL_PREF and no workspace preference), the token is expired/revoked, the model id isn't served by Gitee AI, or the server has no egress to ai.gitee.com.","commonSituations":"Provider configured with a key but no model pref, so the request carries model:''; Gitee token rotated but .env still holds the old one; model id copied from Gitee's docs pages with wrong casing.","solutions":["Set a valid model via GITEE_AI_MODEL_PREF or the workspace model picker (this class defaults the model to '' which always fails)","If the inner message says 401/unauthorized, regenerate the Gitee AI token and update GITEE_AI_API_KEY","If 429, respect Gitee AI rate limits / check quota","Verify egress: curl -H \"Authorization: Bearer $GITEE_AI_API_KEY\" https://ai.gitee.com/v1/models"],"exampleFix":"# before (.env)\nGITEE_AI_API_KEY=... # no model -> model:\"\" sent\n\n# after (.env)\nGITEE_AI_API_KEY=...\nGITEE_AI_MODEL_PREF=Qwen2.5-72B-Instruct","handlingStrategy":"try-catch","validationCode":"// this class defaults this.model to '' — never chat without an explicit model\nconst model = modelPreference || process.env.GITEE_AI_MODEL_PREF;\nif (!model) return respond(\"Select a Gitee AI model first (GITEE_AI_MODEL_PREF or workspace setting).\");\n// optional: verify it against the live catalog\nconst r = await fetch(\"https://ai.gitee.com/v1/models\", { headers: { Authorization: `Bearer ${process.env.GITEE_AI_API_KEY}` } });\nif (r.status === 401) return respond(\"Gitee AI token invalid/expired.\");","typeGuard":null,"tryCatchPattern":"try {\n  return await llm.getChatCompletion(messages);\n} catch (err) {\n  if (/401|Unauthorized/i.test(err.message)) return respond(\"Regenerate your Gitee AI access token.\");\n  if (/404|model/i.test(err.message)) return respond(\"Model id not found on Gitee AI — re-select it.\");\n  if (/429|rate/i.test(err.message)) return backoffAndRetry();\n  throw err;\n}","preventionTips":["Always pin GITEE_AI_MODEL_PREF — the empty-string default guarantees a failed request","Verify the token with a /models call during provider setup","Handle expired tokens proactively since Gitee tokens rotate"],"tags":["gitee-ai","openai-compat","api-error-passthrough"],"backgroundTag":"openai-api-error","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}