OpenAI reasoning.effort "Unsupported value" (unsupported_value): Causes and Fixes
You set a reasoning effort — none, minimal, max — and the API returns HTTP 400 saying the value is not supported with this model, followed by a list of the values that are. Here is why reasoning effort is validated per model, which current models accept which levels, and how to stop hard-coding a single value across models.
Quick answer
unsupported_value on reasoning.effort (Responses) or reasoning_effort (Chat Completions) means the model supports a reasoning effort, just not the level you sent. Support differs per model: gpt-6.1-sol and gpt-6-astra reject none; none of the current GPT-6 or GPT-5.6 Sol model pages list minimal. Use a value from the "Supported values" list in the error message — low is OpenAI's suggested replacement for both none (on models without it) and minimal — and keep a per-model map instead of one global setting.
Symptoms and What the Error Means
On the Responses API, sending none to a model that doesn't accept it looks like this:
{
"error": {
"message": "Unsupported value: 'none' is not supported with the 'gpt-6-astra' model. Supported values are: 'low', 'medium', 'high', 'xhigh', and 'max'.",
"type": "invalid_request_error",
"param": "reasoning.effort",
"code": "unsupported_value"
}
}The same message appears for gpt-6.1-sol:
Unsupported value: 'none' is not supported with the 'gpt-6.1-sol' model. Supported values are: 'low', 'medium', 'high', 'xhigh', and 'max'.Two things make this error easy to act on:
- The message names the model that rejected the value, which matters when a client silently switched models under you.
- It lists the accepted values. You don't need to guess — any value from that list will pass validation.
Don't confuse it with its neighbor:
{
"error": {
"message": "Unsupported parameter: 'reasoning.effort' is not supported with this model.",
"type": "invalid_request_error",
"param": "reasoning.effort",
"code": "unsupported_parameter"
}
}unsupported_parameter means the model takes no reasoning effort at all — usually a non-reasoning model. The fix there is to omit the reasoning object entirely. For the wider family of parameter errors (max_tokens, temperature), see Unsupported parameter: max_tokens.
Why It Happens
- The value list is a superset. OpenAI's API reference lists
none,minimal,low,medium,high,xhighandmaxfor bothreasoning.effortandreasoning_effort, and adds that not every reasoning model supports every value. The authoritative list for a given model is on its model page. - One effort setting, many models. A global config value (
reasoning_effort = "none"for speed,minimalfrom an older setup) is fine on one model and rejected on the next. - A client switched the model but kept the effort. OpenAI's Codex repository has several issues where the app moved a thread to
gpt-6-astrawhile keeping an effort ofnone, and every following request failed with this error. minimalis a carry-over. It appears in the API's value list, but none of the current model pages checked for this article (gpt-6.1-sol,gpt-6-astra,gpt-6-sol,gpt-6-luna,gpt-5.6-sol) include it.
Which Models Accept Which Values
From OpenAI's model pages, as of 2026-11-13:
| Model | none | minimal | low | medium | high | xhigh | max |
|---|---|---|---|---|---|---|---|
gpt-6.1-sol | — | — | ✓ | ✓ (default) | ✓ | ✓ | ✓ |
gpt-6-astra | — | — | ✓ | ✓ | ✓ | ✓ | ✓ |
gpt-6-sol | ✓ | — | ✓ | ✓ (default) | ✓ | ✓ | ✓ |
gpt-6-luna | ✓ | — | ✓ | ✓ (default) | ✓ | ✓ | ✓ |
gpt-5.6-sol | ✓ | — | ✓ | ✓ (default) | ✓ | ✓ | ✓ |
Both API references document medium as the default when you omit the field. Support changes as models ship, so re-check the model page — or simply read the "Supported values" list in the error — rather than treating this table as permanent.
Fix 1: Send a Value the Model Accepts
The smallest fix: use one of the values from the error. On the Responses API:
curl https://byesu.com/v1/responses \
-H "Authorization: Bearer sk-YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-astra",
"input": "Find the off-by-one bug in: for i in range(1, len(xs)): print(xs[i])",
"reasoning": {"effort": "low"}
}'On Chat Completions, the same setting is a top-level string:
curl https://byesu.com/v1/chat/completions \
-H "Authorization: Bearer sk-YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-astra",
"messages": [{"role": "user", "content": "Find the off-by-one bug in: for i in range(1, len(xs)): print(xs[i])"}],
"reasoning_effort": "low"
}'OpenAI's GPT-6 migration guidance gives two specific substitutions: on gpt-6-astra and gpt-6.1-sol, use low where you used none; and if a request used minimal, start with low and compare results.
Fix 2: Keep a Per-Model Effort Map
If your code calls more than one model, make the effort a function of the model, with a fallback that moves to the nearest supported level instead of failing:
from openai import OpenAI
client = OpenAI(api_key="sk-YOUR_TOKEN", base_url="https://byesu.com/v1")
LEVELS = ["none", "minimal", "low", "medium", "high", "xhigh", "max"]
SUPPORTED = {
"gpt-6.1-sol": {"low", "medium", "high", "xhigh", "max"},
"gpt-6-astra": {"low", "medium", "high", "xhigh", "max"},
"gpt-6-sol": {"none", "low", "medium", "high", "xhigh", "max"},
"gpt-6-luna": {"none", "low", "medium", "high", "xhigh", "max"},
"gpt-5.6-sol": {"none", "low", "medium", "high", "xhigh", "max"},
}
def effort_for(model: str, wanted: str) -> str | None:
allowed = SUPPORTED.get(model)
if allowed is None:
return None # unknown model: let the API default apply
if wanted in allowed:
return wanted
i = LEVELS.index(wanted)
# Prefer the next level up (more reasoning), then look down
for lvl in LEVELS[i + 1:] + LEVELS[:i][::-1]:
if lvl in allowed:
return lvl
return None
def ask(model: str, prompt: str, wanted: str = "none"):
kwargs = {"model": model, "input": prompt}
effort = effort_for(model, wanted)
if effort:
kwargs["reasoning"] = {"effort": effort}
return client.responses.create(**kwargs)
print(effort_for("gpt-6-astra", "none")) # -> low
print(effort_for("gpt-6-luna", "minimal")) # -> lowRounding up rather than down is a deliberate choice: a request that asked for very little reasoning gets slightly more, which costs some latency but rarely hurts quality. Flip the order if latency matters more to you.
Fix 3: Retry Once Using the Error's Own List
When you cannot maintain a table — say, a proxy in front of many models — parse the "Supported values" list and retry exactly once:
import re
import openai
def create_with_effort(**kwargs):
try:
return client.responses.create(**kwargs)
except openai.BadRequestError as e:
err = (e.body or {}).get("error", e.body) or {}
if err.get("code") != "unsupported_value" or err.get("param") != "reasoning.effort":
raise
allowed = re.findall(r"'([a-z]+)'", err.get("message", "").split("Supported values are:")[-1])
if not allowed:
raise
fallback = "low" if "low" in allowed else allowed[0]
kwargs["reasoning"] = {**kwargs.get("reasoning", {}), "effort": fallback}
return client.responses.create(**kwargs)Log every fallback. A silent downgrade from max to xhigh, or an upgrade from none to low, changes latency and output length, and you want to know when it happens.
Effort Interacts With Tools and Sampling
Picking an effort is not only a validation question:
- Sampling parameters. OpenAI's migration guidance says to remove
temperature,top_pandtop_logprobswhenever effort is notnone. If you switchgpt-6-lunafromnonetolow, drop those fields too — see Unsupported parameter: max_tokens. - Function calling on Chat Completions. Per OpenAI's model pages,
gpt-6-solandgpt-6-lunasupport function calling on Chat Completions only atreasoning_effort: "none", andgpt-6.1-sol/gpt-6-astraneed the Responses API for tool calling. If you were usingnonejust to get tools on Chat Completions, moving to Responses is the cleaner fix. - Speed and token use. The API reference notes that lower effort can mean faster responses and fewer reasoning tokens. Reasoning tokens count toward the output cap and context window, so a high effort can also surface as a context length or output-cap problem.
Codex and Other Clients
Codex reads its effort from model_reasoning_effort in ~/.codex/config.toml. If you switch models, check that the effort is valid for the new one — none works on gpt-6-sol but not on gpt-6-astra or gpt-6.1-sol. The byesu Codex CLI guide shows a working config. In any client with an effort dropdown, the same rule applies: the dropdown may offer levels the selected model will reject.
If You're Calling GPT Through byesu
byesu is an AI API gateway with an OpenAI-compatible endpoint at https://byesu.com/v1, supporting both Chat Completions and Responses, billed pay-as-you-go with no subscription.
- Both parameter shapes work. Use
reasoning_efforton/v1/chat/completionsandreasoning.efforton/v1/responses; the per-model value rules above still decide what is accepted. - Check the model string first. Since the error names the model, compare it with the ID you meant to call — copy IDs from the console model list or
GET /v1/models.
To get set up, follow the Quick Start.
FAQ
What does "Unsupported value: 'none' is not supported with the model" mean?
It is a 400 invalid_request_error with param reasoning.effort and code unsupported_value. The model accepts the reasoning effort setting, but not the level you sent. The message lists the supported values; pick one of those and resend.
Which reasoning effort values does OpenAI support?
The API reference lists none, minimal, low, medium, high, xhigh and max, and notes that not every reasoning model supports every value. Support is per model: for example, gpt-6.1-sol and gpt-6-astra accept low through max but not none or minimal, while gpt-6-sol, gpt-6-luna and gpt-5.6-sol also accept none.
What should I use instead of minimal?
OpenAI's GPT-6 migration guidance says to start with low when moving a request that used minimal, then compare results. On gpt-6.1-sol and gpt-6-astra, use low wherever you previously used none as well.
What is the difference between reasoning_effort and reasoning.effort?
They are the same setting in two APIs. Chat Completions takes a top-level reasoning_effort string; the Responses API takes a reasoning object with an effort field. Both default to medium when omitted, and both validate the value against the model.
Why do I get "Unsupported parameter: 'reasoning.effort'" instead?
That variant, with code unsupported_parameter, means the model does not take a reasoning effort at all, typically because it is not a reasoning model. Omit the whole reasoning object for that model rather than trying a different value.
