The Chat Template Ignored enable_thinking

2026-09-25Updated 2026-09-27The Model Zoo

Three different ways of switching thinking off all left one model thinking at its maximum setting, because its chat template never reads any of them. It reads only reasoning_effort, and treats every value except two as 'Max'. A two-render check at startup finds this in any template.

Summary

Clients switch a reasoning model's thinking off in one of a few conventional ways: enable_thinking: false in the template arguments, thinking: false, or reasoning_effort: "none". On GLM-5.3, served by our own engine, all three did nothing — and not "nothing" as in the default, but thinking at Max. The model's chat template has no enable_thinking variable at all. It reads one argument, reasoning_effort, recognizes two values, low and high, and renders anything else — including none, and including the argument being absent — as Reasoning Effort: Max. An agent workload we were running had quietly learned to send reasoning_effort: "low" by hand, which is how we found out. The fix is a startup probe that renders the template twice and compares.

Why nobody noticed

A template is Jinja. It does not reject arguments it does not use; an unknown key is just an undefined variable, and an undefined variable in a condition is false. So the request is accepted, the response is correct, and the only difference is that it took far longer and spent far more tokens than the client asked for. No error, no warning, a 200.

We had seen the same symptom on a different model and a different server six weeks earlier — the documented thinking switch behaved exactly like the default, and so did reasoning_effort: "none". That time we measured the cost and routed around it. This time we read the template, and the cause was sitting in it.

The check

Render the prompt three ways and compare the strings:

  1. no template arguments;
  2. enable_thinking: false;
  3. reasoning_effort: "low".

If (2) is byte-identical to (1), the template does not honor enable_thinking. If (3) differs from (1), the template has an effort knob you can use instead. For GLM-5.3 that is exactly what came out: (2) rendered like (1), (3) did not.

Our server now runs that probe once per template at startup. For a template that fails it, a client's thinking-off request is passed through as reasoning_effort: "low", with the same 1,024-token thinking budget an explicit low gets. For a template that honors enable_thinking, nothing changes; Qwen3.8's does, and it is untouched.

Two honest caveats. "Low" is not "off." The model still opens a think block and thinks briefly; there is no value in this template that renders no thinking at all. And the server's split of reasoning from answer follows the rendered prompt, so it stays correct in both modes, but a client that expects zero reasoning tokens will still see some.

Verdict

"Thinking off" is not a standard; it is whatever each model's template happens to read. Before you trust any reasoning switch on a new model, render the template with and without it and diff the two. If they match, your switch is decorative, and the model is running at whatever the template's fallback is — which, for this one, was the most expensive setting it has.

Related: what thinking mode actually costs and four reasons your config edit didn't take.


Everything in these notes I also do for hire: local AI set up on hardware you own, configured on-site, then handed over with enough documentation that you do not need me afterward. If that sounds more useful than another weekend of reading forum threads, the details are at /work. No obligation from an email, and the posts stay free either way.

See pricing and book an audit →