Result first. We sent M2.x-style requests to MiniMax M3.1 Flash through AIHubMix on 19 October 2026. Three things broke or changed:
- Disabling thinking on Chat Completions returns HTTP 400, code 2013, "requires adaptive thinking".
- Every other way of asking for "no thinking" returns 200 and the model thinks anyway.
- With no effort set, the model runs at max: on a small bug fix that meant about 6,400 reasoning tokens and 56 seconds, against about 600 tokens and 9.5 seconds at
low. Both settings passed all 215 tests.
The rest of this post is the error, a minimal repro, the fixes, and what we couldn't verify.
Why this matters now
MiniMax retires M2.5 and M2.7 (plus the -highspeed variants) on 18 November 2026. Since 19 October, both families have been closed to new users. Requests on M Plan and Token Plan that name them are served by M3.1 Flash under the old name, per MiniMax's models page. Pay-as-you-go calls keep working until the retirement date, then stop: "Once retired, API requests to these models will no longer work." M2.1 and M2 aren't in the notice.
If you're on a plan, your logs still say M2.7 but the model behind it has changed: 1M context instead of 204,800, top_p 0.95 instead of 0.9, and thinking at max by default. Re-run your evals.
Prerequisites
- An AIHubMix key in
AIHUBMIX_API_KEY. - Model ID on AIHubMix:
minimax-m3.1-flash. Responses report the upstream name asMiniMax-M3.1-Flash. - Endpoints that work for this model on AIHubMix (all tested):
/v1/chat/completions,/v1/messages,/v1/responses.
The 400: repro and fix
curl https://aihubmix.com/v1/chat/completions \
-H "Authorization: Bearer $AIHUBMIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "minimax-m3.1-flash",
"messages": [{"role": "user", "content": "hi"}],
"thinking": {"type": "disabled"}}'
Response, copied from our run:
{"error": {"message": "invalid params, model \"MiniMax-M3.1-Flash\" requires adaptive thinking; thinking.type=\"disabled\" (including reasoning.effort=none) is not allowed (2013) (tid: …)", "type": "bad_request_error", "param": "", "code": null}}
MiniMax's Messages API reference says the model "always thinks"; thinking.type, if sent, must be adaptive. Code written for M3 can hit this, because M3 can turn thinking off. Frameworks that classify the model as non-reasoning and send "thinking off" by default fail on every call, as the kodus-ai and 9router-go projects reported.
Fix: drop thinking, or send {"type": "adaptive"}. To make calls faster, lower the effort:
import os
from openai import OpenAI
client = OpenAI(base_url="https://aihubmix.com/v1", api_key=os.environ["AIHUBMIX_API_KEY"])
resp = client.chat.completions.create(
model="minimax-m3.1-flash",
reasoning_effort="low", # low | medium | high | xhigh | max; omitted = max
max_tokens=32768, # thinking counts toward this
messages=[{"role": "user", "content": "Explain in two sentences why the sky is blue."}],
)
print(resp.choices[0].finish_reason, resp.usage.completion_tokens_details.reasoning_tokens)
Same code 2013, different cause
invalid param: remote returned status 400 (2013) came back for an image URL on upload.wikimedia.org. The same request with a base64 image, or an image URL from another host, returned 200. 2013 is MiniMax's general invalid-params code. Our reading of this message is that the upstream couldn't fetch the image; MiniMax doesn't document the case. Send images as data:image/png;base64,… and read the full message before grepping logs for 2013.
Quiet failure modes (all return 200)
| Request through AIHubMix | What actually happens |
|---|---|
| Messages, thinking disabled | Still thinks: 469–622 tokens on a short puzzle |
| Chat, reasoning_effort none | Still thinks: 265–372 tokens on the same puzzle |
| Chat, reasoning_effort minimal | Still thinks (one run, arithmetic prompt) |
| Effort omitted | Runs at max |
| max_tokens 64 | finish_reason length, answer cut mid-sentence |
| cache_control blocks | Not supported; caching is automatic |
| service_tier | Not supported; no Priority tier |
The puzzle rows are three runs each; low used 173–251 reasoning tokens on the same puzzle. Only Chat Completions with thinking: {"type": "disabled"} produces the 400.
Effort cost, measured. The task was a two-bug fix in one Python function, graded against 215 hidden tests. It ran three times per setting on Chat Completions.
| Setting | Avg reasoning tokens | Avg time | Avg cost per fix |
|---|---|---|---|
| Effort omitted | 6,364 | 56 s | $0.0045 |
| Effort low | 591 | 9.5 s | $0.0006 |
All runs passed. Prices are AIHubMix's: $0.165 input, $0.66 output, and $0.0165 cache read per 1M tokens. Thinking is billed as output, and it was 95% of the output at default (6,364 of 6,673 tokens).
Truncation. With max_tokens: 64 and a two-sentence question, the response was finish_reason: "length" with content "Sunlight contains many colors,". MiniMax recommends 131,072 and allows 524,288.
Caching. cache_control isn't supported on M3.1 Flash (or M3). M2.7 billed explicit cache writes at $0.375 per 1M tokens. Every request we sent, even the first, had about 175–195 prompt tokens served from cache. It looks like a fixed MiniMax-side preamble, and it costs about a third of a cent per thousand requests at AIHubMix's cache-read price.
Pricing gaps. MiniMax's pricing page has no per-token price for M3.1 Flash yet. M3's official price doubles above 512K input tokens; AIHubMix lists one flat price for M3.1 Flash, so check your first invoice if you send very long prompts.
Agents and coding tools
Agent behaviour that matters:
- It reasons before every tool call, even at
low; our short tool steps took about 2–7 s. - It follows instructions narrowly. An early tester called it "insanely fast, but it needs clear and specific instructions, otherwise it's too lazy." Give explicit stop conditions and verification steps.
- MiniMax documents
tool_choiceasautoonly. AIHubMix accepted"required"and{"type": "any"}and the tool was called, but forcing isn't documented. Don't rely on it. - Return thinking blocks unchanged (Messages) and keep
reasoning_contentintact (Chat), per MiniMax. A stripped short round trip worked in our test; long loops should follow the rule.
Protocol support, tested on 19 October with text, a tool call, and a tool-result round trip:
| Tool | Protocol | Works via AIHubMix | Effort field |
|---|---|---|---|
| Claude Code | Anthropic Messages | Yes | output_config.effort |
| Codex CLI | OpenAI Responses | Yes | reasoning.effort |
| OpenCode | OpenAI-compatible | Yes | reasoning_effort |
Claude Code (AIHubMix guide):
export ANTHROPIC_BASE_URL="https://aihubmix.com"
export ANTHROPIC_AUTH_TOKEN="$AIHUBMIX_API_KEY"
export ANTHROPIC_MODEL="minimax-m3.1-flash"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="minimax-m3.1-flash"
thinking: enabled with a budget and thinking: adaptive both returned 200.
Codex CLI (AIHubMix guide): use a custom provider with wire_api = "responses", model = "minimax-m3.1-flash", and model_reasoning_effort. Function calls come back as function_call items. xhigh and minimal were accepted. minimal isn't a MiniMax level, so the model still thinks.
OpenCode: issue #54801 (reproduced on v2.0.27) says OpenCode resolves no effort variants for this model. The workaround is to declare five variants in opencode.json. Through AIHubMix's OpenAI-compatible provider, each variant should set reasoning_effort (low … max) rather than the issue's output_config.effort. Don't add none.
The context window is 1,000,000 on MiniMax's API. MiniMax Code's own client defaults to 512K "to balance experience and cost", per a maintainer's quote of MiniMax's docs in the magpie project. The API has no window parameter.
Smoke test (about 15 minutes): give the agent a scratch folder with one known bug and a failing test, and ask it to "Run the tests, fix the bug, run the tests again, and show me the output." Pass criteria: tests run before and after, the final run is green, it takes a few turns, and no turn returns a 400. In the AIHubMix usage log, minimax-m3.1-flash requests should show reasoning tokens. If turns take close to a minute, the effort setting isn't reaching the model.
What we couldn't verify
-
Claude Code effort. Whether Claude Code's effort setting reaches a non-Claude model as
output_config.effortisn't documented. If it doesn't, the model runs atmax. -
Forced tool calls. Whether
tool_choiceforcing is enforced or the model just happened to call the tool. - The image error. Why the Wikimedia URL failed; our explanation is a reading of the error text.
- Long tool loops. Whether stripping thinking blocks breaks them. Our test was one short round trip.
-
AIHubMix's own M2.7 route. What happens to
minimax-m2.7on AIHubMix after 18 November isn't stated. MiniMax's retirement applies to MiniMax's API. - Sample size. All timings come from three runs per setting, so treat small differences as noise.
Keep reading: the MiniMax M3.1 Flash series
- What you're migrating to, from the Space Bunny launch to its price against M2.7 and M3: MiniMax M3.1 Flash (ex-Space Bunny) on the API: Specs, Price, and a Measured Bug-Fix Cost
- The effort setting decides most of your post-migration bill. All five levels, measured on one fix: Measuring MiniMax M3.1 Flash's Five Effort Levels on One Bug Fix
- If you're reconsidering MiniMax altogether, the same task on its two closest rivals: MiniMax M3.1 Flash vs DeepSeek V4.1 Flash vs Claude Haiku 5.5: Same Bug Fix, Measured
Top comments (0)