{"record":{"id":"76a3858fdff9d780","repo":"Mintplex-Labs/anything-llm","slug":"invalid-response-body-returned-from-minimax-jso","errorCode":null,"errorMessage":"Invalid response body returned from Minimax: ${JSON.stringify(result.output)}","messagePattern":"Invalid response body returned from Minimax: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/AiProviders/minimax/index.js","lineNumber":104,"sourceCode":"      );\n\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 Minimax: ${JSON.stringify(result.output)}`\n      );\n\n    return {\n      textResponse: result.output.choices[0].message.content,\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":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/utils/AiProviders/minimax/index.js#L86-L122","documentation":"After MinimaxLLM.getChatCompletion receives a response, LLMPerformanceMonitor.measureAsyncFunction wraps it as { output, duration }, and the provider requires output.choices to be a non-empty array. SDK/API errors are re-thrown earlier via .catch((e) => new Error(e.message)), so reaching this throw means the request technically completed but the body had no usable choices — a malformed or unexpected payload from the MiniMax-compatible endpoint.","triggerScenarios":"MiniMax returns HTTP 200 with an error object or empty choices (billing/quota wrapped in a 200, content-filtered response, truncated body); an intermediate gateway or proxy rewrites the response; the model serves a non-chat response shape; result.output is null/undefined.","commonSituations":"Expired prepaid credits where the API replies 200 with an error payload; OpenAI-compatible proxies in front of api.minimax.io; upstream incidents; payloads where usage is present but choices is empty.","solutions":["Log the full e.message — it embeds JSON.stringify(result.output), which shows exactly what MiniMax returned","Check the MiniMax console for quota/billing status and top up if empty","Confirm you are calling a chat-capable model id from GET /v1/models","If behind a proxy, bypass it and call api.minimax.io directly to compare the raw response","Retry once — transient malformed bodies during upstream incidents do occur"],"exampleFix":"// before\nconst res = await minimax.getChatCompletion(messages);\n// after — surface the raw body when the shape is wrong\ntry {\n  const res = await minimax.getChatCompletion(messages);\n} catch (e) {\n  if (e.message.startsWith('Invalid response body returned from Minimax'))\n    console.error('MiniMax unexpected body:', e.message);\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function hasChoices(result) {\n  return Array.isArray(result?.output?.choices) && result.output.choices.length > 0;\n}","tryCatchPattern":"try {\n  const res = await minimax.getChatCompletion(messages);\n} catch (e) {\n  if (e.message.startsWith('Invalid response body returned from Minimax')) {\n    // e.message embeds JSON.stringify(result.output): log it, check quota/billing, retry once\n  }\n  throw e;\n}","preventionTips":["Monitor MiniMax quota/billing so the API does not 200-with-error-body","Log the embedded raw body whenever this fires to identify failure shapes","Keep a fallback provider for user-facing chat requests","Bypass intermediate proxies when debugging to compare raw responses"],"tags":["minimax","anythingllm","api-response","malformed-response","chat-completion"],"backgroundTag":"malformed-api-response","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"}