Skip to content

OpenAI "Unsupported parameter: 'max_tokens'" (unsupported_parameter): Causes and Fixes ​

You send a Chat Completions request to a reasoning model and get HTTP 400 telling you max_tokens is not supported and to use max_completion_tokens instead. A close cousin rejects temperature or top_p. Here is what changed, how the three output-cap fields map across APIs, and how to clean up the request.

Quick answer

Reasoning models reject the legacy max_tokens field on Chat Completions — OpenAI deprecated it in favor of max_completion_tokens. Rename the field. On the Responses API the same cap is called max_output_tokens. The related errors for temperature, top_p and logprobs mean those sampling parameters are not accepted at the reasoning effort you are using: remove them. All of these fail at validation time, before the model generates anything.

Symptoms and What the Error Means ​

The classic body, as reported against OpenAI's own Python SDK:

json
{
  "error": {
    "message": "Unsupported parameter: 'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead.",
    "type": "invalid_request_error",
    "param": "max_tokens",
    "code": "unsupported_parameter"
  }
}

The sampling-parameter version has the same shape:

json
{
  "error": {
    "message": "Unsupported parameter: 'temperature' is not supported with this model.",
    "type": "invalid_request_error",
    "param": "temperature",
    "code": "unsupported_parameter"
  }
}

Some models accept the parameter name but only its default value, and the message changes accordingly:

text
Unsupported value: 'temperature' does not support 0 with this model. Only the default (1) value is supported.

How to read them:

  • unsupported_parameter — the field itself is not allowed for this model. Remove or rename it.
  • unsupported_value — the field is allowed, but not with the value you sent. For reasoning.effort this is a separate problem; see reasoning effort unsupported value.
  • param tells you exactly which field to fix. Read it before changing anything else.

Because the request never reached generation, retrying the same body will fail the same way — this is not a transient error.

Why It Happens ​

  1. max_tokens is deprecated on Chat Completions. OpenAI's API reference marks it deprecated in favor of max_completion_tokens and states it is not compatible with o-series models. In practice the GPT-5 family and newer reasoning models reject it the same way, so treat every reasoning model as max_completion_tokens-only.
  2. The cap now covers reasoning. max_completion_tokens (Chat Completions) and max_output_tokens (Responses) both count reasoning tokens as well as visible output. The rename makes that change of meaning explicit.
  3. Sampling controls depend on reasoning effort. OpenAI's GPT-6 migration guidance says to drop temperature, top_p and top_logprobs whenever reasoning effort is anything other than none, plus logprobs on Chat Completions.
  4. Something else is adding the field. SDK wrappers, agent frameworks and CLIs frequently inject max_tokens or a default temperature that you never wrote. OpenAI's own repositories have issues of exactly this kind — a CLI sending temperature/top_p to o3-mini, and an agents library sending max_tokens to reasoning models.

The Three Output-Cap Fields at a Glance ​

Chat CompletionsResponses API
Output capmax_completion_tokens (max_tokens is deprecated)max_output_tokens (minimum 16)
Includes reasoning tokensYesYes
Reasoning effort fieldreasoning_effort (top level)reasoning: { "effort": ... }
When the cap is hitfinish_reason: "length"status: "incomplete", incomplete_details.reason: "max_output_tokens"

Field names do not carry across: max_completion_tokens belongs to Chat Completions and max_output_tokens to Responses. Some OpenAI-compatible gateways have also been reported to reject max_output_tokens, so if you move between providers, re-test the field name against each endpoint.

Fix 1: Rename max_tokens to max_completion_tokens ​

The direct fix on Chat Completions:

bash
curl https://byesu.com/v1/chat/completions \
  -H "Authorization: Bearer sk-YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6-sol",
    "messages": [{"role": "user", "content": "Summarize RFC 9110 in three bullets."}],
    "max_completion_tokens": 4000
  }'

With the OpenAI Python SDK:

python
from openai import OpenAI

client = OpenAI(api_key="sk-YOUR_TOKEN", base_url="https://byesu.com/v1")

resp = client.chat.completions.create(
    model="gpt-6-sol",
    messages=[{"role": "user", "content": "Summarize RFC 9110 in three bullets."}],
    max_completion_tokens=4000,   # not max_tokens
)
print(resp.choices[0].finish_reason, resp.choices[0].message.content)

If the code also has to serve older non-reasoning models, keep a single internal setting and translate it at the edge rather than sending both fields.

Fix 2: On the Responses API, Use max_output_tokens ​

If you are already on (or moving to) /v1/responses, the field is different again:

bash
curl https://byesu.com/v1/responses \
  -H "Authorization: Bearer sk-YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6.1-sol",
    "input": "Summarize RFC 9110 in three bullets.",
    "reasoning": {"effort": "low"},
    "max_output_tokens": 4000
  }'
python
resp = client.responses.create(
    model="gpt-6.1-sol",
    input="Summarize RFC 9110 in three bullets.",
    reasoning={"effort": "low"},
    max_output_tokens=4000,
)
if resp.status == "incomplete":
    print("Cap reached:", resp.incomplete_details.reason)
else:
    print(resp.output_text)

The Responses API matters for current models beyond the field name: per OpenAI's model pages, tool calling on gpt-6.1-sol and gpt-6-astra requires Responses, and gpt-6-sol / gpt-6-luna only support function calling on Chat Completions at reasoning_effort: "none".

Fix 3: Strip Sampling Parameters That Don't Apply ​

Follow OpenAI's GPT-6 migration rule: when reasoning effort is not none, remove temperature, top_p and top_logprobs; on Chat Completions also remove logprobs; on Responses remove message.output_text.logprobs from include.

Which models can run at none (per OpenAI's model pages):

ModelAccepts reasoning.effort: "none"Sampling params usable?
gpt-6.1-solNoPlan on never sending them
gpt-6-astraNoPlan on never sending them
gpt-6-solYesOnly at effort none
gpt-6-lunaYesOnly at effort none
gpt-5.6-solYesAssume only at effort none

A small sanitizer keeps this out of your call sites:

python
SAMPLING_KEYS = ("temperature", "top_p", "top_logprobs", "logprobs")

def clean_chat_params(params: dict) -> dict:
    p = dict(params)
    # Legacy cap -> current cap
    if "max_tokens" in p:
        p.setdefault("max_completion_tokens", p.pop("max_tokens"))
    # Sampling controls only make sense at effort "none"
    if p.get("reasoning_effort", "medium") != "none":
        for k in SAMPLING_KEYS:
            p.pop(k, None)
    return p

resp = client.chat.completions.create(**clean_chat_params({
    "model": "gpt-6-luna",
    "messages": [{"role": "user", "content": "ping"}],
    "max_tokens": 200,
    "temperature": 0.2,
}))

The default is treated as medium because both API references document medium as the default effort. The API reference also notes that stop is not supported on o3 and o4-mini, so if you still run those, add stop to the list.

Fix 4: Find the Layer That Adds the Field ​

If your own code never sets max_tokens or temperature, something in between does. Look at the request as it leaves the process:

bash
# openai-python: log request options, including the JSON body
OPENAI_LOG=debug python your_script.py 2>&1 | grep -i -E "max_tokens|temperature|top_p"

Common sources:

  • Framework model settings with a default max_tokens or temperature (agent frameworks, LangChain-style wrappers, eval harnesses).
  • CLI tools that fill in defaults on every call.
  • Client apps with a "max tokens" or "temperature" slider that is always sent, even when untouched.

Fix it where it is injected — usually a model-settings object or a provider config — rather than patching around it per call.

Don't Set the Cap Too Low ​

Because the cap includes reasoning tokens, a tight max_completion_tokens or max_output_tokens can be consumed entirely by reasoning. OpenAI's reasoning guide warns that the cut-off can happen before any visible output is produced, and suggests reserving at least 25,000 tokens for reasoning and output while you experiment. If you get finish_reason: "length" with an empty message, raise the cap or lower the effort. That is a budget problem, not the context-window error — for that one, see context length exceeded.

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.

  • Same rules, same fields. The parameter guidance above applies unchanged: max_completion_tokens on /v1/chat/completions, max_output_tokens on /v1/responses, and no sampling parameters at reasoning efforts other than none.
  • Exact model IDs. Copy IDs such as gpt-6.1-sol or gpt-6-luna from the console model list or GET /v1/models so the parameter rules you apply match the model you actually call.

To get set up, follow the Quick Start.

FAQ ​

What does "Unsupported parameter: 'max_tokens' is not supported with this model" mean? ​

It is a 400 invalid_request_error with code unsupported_parameter. Reasoning models on Chat Completions do not accept the legacy max_tokens field, which OpenAI has deprecated in favor of max_completion_tokens. Rename the field and the request goes through; the error is raised during validation, before the model generates anything.

What is the difference between max_tokens, max_completion_tokens and max_output_tokens? ​

max_tokens is the deprecated Chat Completions cap. max_completion_tokens is its replacement on Chat Completions and covers both visible output and reasoning tokens. max_output_tokens is the equivalent cap on the Responses API (minimum 16), and it also includes reasoning tokens.

Why does my reasoning model reject temperature or top_p? ​

OpenAI's migration guidance for GPT-6 says to remove temperature, top_p and top_logprobs whenever reasoning effort is not none, and to remove logprobs on Chat Completions as well. Models that cannot run at effort none, such as gpt-6.1-sol and gpt-6-astra, should never receive these sampling parameters.

Why does the error appear when I never set max_tokens or temperature? ​

A library, framework or CLI is adding it for you. SDK wrappers and agent frameworks often inject max_tokens or a default temperature. Log the raw outgoing request body and remove the field at the layer that adds it.

Can I set max_completion_tokens too low on a reasoning model? ​

Yes. The cap includes reasoning tokens, so a small value can be used up by reasoning before any visible text appears. OpenAI suggests reserving at least 25,000 tokens for reasoning and output when you first experiment with reasoning models.

Got a problem? Contact support or join our group.