{"record":{"id":"b46103d05e151520","repo":"Mintplex-Labs/anything-llm","slug":"invalid-response-body-returned-from-giteeai-jso","errorCode":null,"errorMessage":"Invalid response body returned from GiteeAI: ${JSON.stringify(result.output)}","messagePattern":"Invalid response body returned from GiteeAI: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/AiProviders/giteeai/index.js","lineNumber":139,"sourceCode":"\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,\n        duration: result.duration,\n        model: this.model,\n        provider: this.className,\n        timestamp: new Date(),\n      },\n    };\n  }\n","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/utils/AiProviders/giteeai/index.js#L121-L157","documentation":"Thrown after a successful HTTP call when the response body is structurally invalid: result.output has no `choices` property, or the choices array is empty. Unlike the catch wrapper, this means the server answered without throwing but the body is not a usable OpenAI-format completion. The full response is JSON-stringified into the message for debugging.","triggerScenarios":"Gitee AI returns 200 with a body missing `choices` — e.g. an error object {error: ...}, an HTML error page parsed as text, a content-filter block with no choices, or a schema change on Gitee's side. The `.hasOwnProperty('choices')` / `choices.length === 0` check then trips.","commonSituations":"Gitee AI content policy rejecting the prompt (returns an object without choices); upstream model crashed and Gitee returned a status envelope; partial/gateway response; API version drift where the response shape changed.","solutions":["Read the JSON.stringify(result.output) embedded in the message — it shows exactly what Gitee returned","If it contains an `error` field, address that cause (content policy, model unavailable)","Retry once in case of a transient gateway/partial response","Check Gitee AI status/changelog for response-schema changes"],"exampleFix":"// before\nif (!result?.output?.hasOwnProperty('choices') || result?.output?.choices?.length === 0)\n  throw new Error(`Invalid response body returned from GiteeAI: ${JSON.stringify(result.output)}`);\n\n// after (surface a structured, type-safe error instead of a stringly one)\nif (!result?.output?.choices?.length)\n  throw new GiteeResponseError('No choices in GiteeAI response', result.output);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isOpenAiCompletion(payload) {\n  return payload != null\n    && Array.isArray(payload.choices)\n    && payload.choices.length > 0\n    && payload.choices[0]?.message != null;\n}","tryCatchPattern":"const result = await llm.getChatCompletion(messages, { temperature }).catch(async (e) => {\n  if (/Invalid response body returned from GiteeAI/.test(e.message)) {\n    // inspect the stringified body in the message, classify (content filter vs outage)\n    if (/content_filter|safety/i.test(e.message)) throw new ContentFilterError(e.message);\n    throw new UpstreamFormatError(e.message);\n  }\n  throw e;\n});","preventionTips":["Validate the response shape with a type guard before reading choices","Retry once on transient gateway/empty-body responses","Log the raw body (as this error does) so content-filter vs outage is distinguishable"],"tags":["giteeai","response-validation","openai-format","chat-completion","content-filter"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}