Mintplex-Labs/anything-llm · error
Invalid response body returned from Minimax
Error message
Invalid response body returned from Minimax: ${JSON.stringify(result.output)} What it means
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.
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
Example fix
// before
const res = await minimax.getChatCompletion(messages);
// after — surface the raw body when the shape is wrong
try {
const res = await minimax.getChatCompletion(messages);
} catch (e) {
if (e.message.startsWith('Invalid response body returned from Minimax'))
console.error('MiniMax unexpected body:', e.message);
throw e;
} Defensive patterns
Strategy: try-catch
Type guard
function hasChoices(result) {
return Array.isArray(result?.output?.choices) && result.output.choices.length > 0;
} Try / catch
try {
const res = await minimax.getChatCompletion(messages);
} catch (e) {
if (e.message.startsWith('Invalid response body returned from Minimax')) {
// e.message embeds JSON.stringify(result.output): log it, check quota/billing, retry once
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Minimax chat: is not valid for chat completion!
- Minimax stream: is not valid for chat completion!
- GroqAI:chatCompletion
- LMStudio chat: is not valid or defined model for chat…
- LocalAI chat: is not valid for chat completion!
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/76a3858fdff9d780.
Report an issue: GitHub.
Appendix: source
Thrown at server/utils/AiProviders/minimax/index.js:104
);
const result = await LLMPerformanceMonitor.measureAsyncFunction(
this.openai.chat.completions
.create({
model: this.model,
messages,
temperature,
})
.catch((e) => {
throw new Error(e.message);
})
);
if (
!result?.output?.hasOwnProperty("choices") ||
result?.output?.choices?.length === 0
)
throw new Error(
`Invalid response body returned from Minimax: ${JSON.stringify(result.output)}`
);
return {
textResponse: result.output.choices[0].message.content,
metrics: {
prompt_tokens: result.output.usage.prompt_tokens || 0,
completion_tokens: result.output.usage.completion_tokens || 0,
total_tokens: result.output.usage.total_tokens || 0,
outputTps: result.output.usage.completion_tokens / result.duration,
duration: result.duration,
model: this.model,
provider: this.className,
timestamp: new Date(),
},
};
}
View on GitHub (pinned to 3aec848f28)