
Gemini 3.6 Flash Migration: Five API Changes and One Silent Failure
TL;DR Migrating togemini-3.6-flashorgemini-3.5-flash-liteinvolves five request changes. Four of them return HTTP 400, so you find out immediately. One of them does not:temperature,top_pandtop_kare now accepted and ignored. If your pipeline relies ontemperature=0for stable output, it will keep returning 200 OK while the guarantee you were counting on is gone. Fix that one first, then the four loud ones.Last verified: 2026-07-21
If you are swapping a model ID in a config file and expecting the rest to keep working, read the first section before you deploy.
The five changes, ranked by how you find out
| Change | What happens on the new models | How you find out |
|---|---|---|
temperature, top_p, top_k | Accepted, then ignored | Nothing. No error, no warning. |
thinking_budget sent together with thinking_level | Request rejected | HTTP 400 |
Last turn in the request has role model | Request rejected | HTTP 400 |
FunctionResponse without call_id and name | Request rejected | HTTP 400 |
candidate_count | Not supported in Gemini 3.x | Request fails or the field is dropped |
Four of these five failures announce themselves. Your integration tests catch them, your error tracker pages you, you fix them in an afternoon. The first one is the one that reaches production.
The dangerous one: temperature, top_p and top_k are now ignored
Read that sequence carefully, because the order matters to you. Today the parameter is a no-op. Later it becomes an error. That means the period where you are most likely to be wrong about your own system is right now, while everything still returns 200.

Which pipelines break without an error
A silent no-op is only dangerous if you were depending on the parameter. Four common setups were:
- Determinism pipelines. Anything that sets
temperature=0to make repeated calls agree with each other: cache keys built from model output, deduplication passes, classification jobs that feed a downstream state machine. The setting is now inert, so whatever output stability it was buying you is no longer being bought. - Golden-file and snapshot tests. Suites that pinned
temperature=0and diff the model's output against a stored expected string. These start flaking after the model swap, and the flake looks like a model quality regression rather than a config problem, which sends you debugging in the wrong direction. - Structured output held together by low temperature. Teams that never adopted structured outputs and instead kept
temperaturenear zero plustop_ptight so the model would reliably emit parseable JSON. Both knobs are now inert at once. - Tuned per-route configs. Products that expose a creativity slider, or route "summarize" at one temperature and "brainstorm" at another. The slider still moves in your UI. It no longer moves anything in the model.
None of these produce a stack trace. They produce output that is slightly different from what you validated, in a system that reports itself healthy.
Your gateway will not warn you either
This is the part that catches even careful teams. Model gateways publish machine-readable metadata describing which parameters each model supports, and tooling reads that metadata to decide what to send.
temperature, top_p and seed in supported_parameters for both google/gemini-3.6-flash and google/gemini-3.5-flash-lite. The gateway accepts those fields and forwards them. The model on the other end ignores them. Nothing in that chain raises an error, and nothing in the metadata tells you the field is dead.What replaces temperature
Google's stated replacement is not another parameter. It is the system instruction: write the behavior you want as a rule the model reads, rather than as a sampling constant.
That is a real change in how you express intent, so translate rather than delete:
| What you used to encode as a number | Where it goes now |
|---|---|
temperature=0 for terse, repeatable answers | A system instruction that states the required format, length and tone, plus a rule to answer with no preamble |
| Low temperature to keep JSON parseable | Structured outputs, which gemini-3.6-flash and gemini-3.5-flash-lite both support |
| High temperature for variety | An instruction asking for N distinct options in one response, since candidate_count is also gone |
temperature and candidate_count in the same migration removes both of the mechanisms teams used for output variety. If a feature of yours depended on variety, it needs an actual redesign, not a config edit.How to find every call site before you deploy
Search your codebase for the parameter names rather than trusting the config layer, because these values are usually set in several places by different people:
# Gemini-native and OpenAI-compatible spellings, plus the config objects that carry them
grep -rn "temperature\|top_p\|topP\|top_k\|topK\|candidate_count\|candidateCount" \
--include="*.py" --include="*.ts" --include="*.js" --include="*.go" --include="*.java" .
# The wrappers that hide them
grep -rn "generation_config\|generationConfig\|GenerateContentConfig\|thinking_budget\|thinkingBudget" .Check the results outside application code too: YAML and JSON config, prompt-management tools, notebooks, eval harnesses, and any Terraform or admin console that stores model settings. A knob set in a dashboard six months ago is exactly the kind of thing that survives a code review.
The four that fail loudly
These are simpler, because the API tells you. Fix them in whatever order your test suite surfaces them.
thinking_budget and thinking_level cannot both be present
thinking_budget with the string enum thinking_level, which takes minimal, low, medium or high. Sending both in one request returns 400. Google's migration note is to replace thinking_budget with thinking_level, not to keep both for compatibility.Two defaults worth knowing while you pick a value, because they differ between the two models:
gemini-3.6-flashdefaults tomedium.gemini-3.5-flash-litedefaults tominimal, which is tuned for throughput.
minimal default on Flash-Lite is not suitable for use as an autonomous sub-agent, and that on multi-step tasks it will terminate tool calls prematurely. If Flash-Lite is going to write code, run terminal commands or call external APIs for you, raise it to medium or high deliberately. This is the one migration edit where accepting the default is an actual product decision rather than a formality.minimal default, on a three-step notification chain, failing all three attempts. The shape was identical each time. It called the first two tools correctly, then stopped and reported success without sending the final notification. No error, no exception, a well-formed response that a downstream service would accept. Raising the same model to high passed the task every time.thinking_level unset, the request will not fail. It will return a confident answer about work it did not finish. Set the level explicitly, then assert on the effects your workflow was supposed to produce rather than on the response you got back.You can no longer prefill a model turn
model, the API returns 400. Prefilling was a common trick: you would append a partial assistant turn like {"role": "model", "parts": [{"text": "{"}]} to force the model to open with a JSON brace, or to suppress a chatty preamble.Both of those goals move into the same two places as everything else: a system instruction that states the rule, or structured outputs when you need a machine-parseable shape. Search your code for any request builder that appends a final assistant or model message, especially retry and continuation logic, which is where prefills tend to be generated dynamically rather than written literally.
Every FunctionResponse needs call_id and name
generateContent API, each FunctionResponse must carry both the matching call_id and the name of the function. Hand-rolled tool loops are the usual casualty here, because plenty of them were written when a bare result was enough and they reconstruct the response object from scratch instead of echoing back what the model sent.call_id from the model's function call, and put it back on the response you return. If you built your tool loop on a framework, update the framework rather than patching around it.candidate_count is gone
candidate_count is not supported in Gemini 3.x. Remove it. If you were using it to sample several answers and pick the best, that logic now has to be explicit: either ask for multiple options inside one response, or issue multiple requests and pay for them separately.Before and after: a request that migrates cleanly
Here is a Gemini-native call carrying every deprecated field, and the version that survives the move.
# BEFORE: works on 2.5-era models, breaks or silently misbehaves on 3.6 Flash
config = {
"temperature": 0, # now ignored, no error
"top_p": 0.95, # now ignored, no error
"top_k": 40, # now ignored, no error
"candidate_count": 1, # unsupported in Gemini 3.x
"thinking_budget": 8192, # 400 if it meets thinking_level
}
# AFTER: intent moved from sampling constants into instructions
config = {
"system_instruction": (
"Answer in at most three sentences. Use plain declarative statements. "
"Do not add a preamble, restate the question, or offer follow-ups. "
"If the answer is uncertain, say so in one sentence."
),
"thinking_level": "medium",
}temperature=0 in a config file never explained itself.import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["EVOLINK_API_KEY"],
base_url="https://api.evolink.ai/v1"
)
response = client.chat.completions.create(
model="gemini-3.6-flash",
messages=[
{"role": "system", "content": "Answer in at most three sentences. No preamble."},
{"role": "user", "content": "Summarize this incident report."}
]
# no temperature, no top_p: they would be accepted and ignored downstream
)
print(response.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env["EVOLINK_API_KEY"],
baseURL: "https://api.evolink.ai/v1",
});
const response = await client.chat.completions.create({
model: "gemini-3.6-flash",
messages: [
{ role: "system", content: "Answer in at most three sentences. No preamble." },
{ role: "user", content: "Summarize this incident report." },
],
// no temperature, no top_p
});
console.log(response.choices[0].message.content);gemini-3.6-flash. There is no preview suffix and no date stamp, so there is no dated alias to pin. If your deployment process assumes a -preview or -001 variant exists, that assumption fails at request time.A migration order that catches the silent failure
The sequence matters, because the loud errors are easy and the quiet one is not. Do it in this order:

- Inventory first. Run the greps above and list every place a sampling parameter is set, including config stores and dashboards. Write down which behavior each one was protecting.
- Translate intent, do not just delete. For every
temperatureyou find, decide what it was for and write the equivalent system instruction. Deleting without translating is how you ship a quality regression. - Fix the 400s. Swap
thinking_budgetforthinking_level, removecandidate_count, remove prefilled model turns, addcall_idandnameto everyFunctionResponse. - Choose a thinking level on purpose, especially on Flash-Lite, where the
minimaldefault is unsuitable for autonomous multi-step work. This is also the largest cost lever in the migration: on our task set, 3.6 Flash atminimalcost 73.6% less per pass than the same model at themediumdefault, and thinking tokens accounted for 85% of billed output atmedium. Whether your workload survives the drop is the thing to test, not whether the saving is real. - Re-baseline your snapshot tests against the new model before you compare anything. Old golden files were produced under a parameter that no longer applies, so they are not a valid reference point.
- Run your evals on both models over the same task set and compare output distributions, not just pass rates. Silent behavior changes show up as drift in format, length and verbosity before they show up as wrong answers.
- Canary on real traffic and watch downstream parsers, not just the API error rate. If something is going to break quietly, it breaks in the code that consumes the model's output, not in the call itself.
temperature=0 still did something, every diff looks like a model problem and none of them are.Let Google's migration skill do the first pass
npx skills add google-gemini/gemini-skills --skill gemini-interactions-api --globalThen, in a coding agent, point it at your project:
/gemini-interactions-api migrate my app to Gemini 3.6 Flash
It is worth running. It handles the mechanical work: finding deprecated fields, rewriting request construction, updating call sites, which covers most of step 3 above.
temperature=0 should be removed. It cannot know that the value was there because a downstream service assumed identical output on identical input, and it cannot write the system instruction that preserves that intent. Treat the skill as a code-sweeping pass, then do the intent translation yourself.Retirement schedule: when the choice stops being yours
| Model | Shutdown date | Recommended replacement |
|---|---|---|
gemini-2.5-flash | 16 October 2026 | gemini-3.6-flash |
gemini-2.5-flash-lite | 16 October 2026 | gemini-3.1-flash-lite |
gemini-3.1-flash-lite | 7 May 2027 | gemini-3.5-flash-lite |
gemini-3-flash-preview | No shutdown date announced | gemini-3.6-flash |
gemini-3.6-flash, gemini-3.5-flash-lite | No shutdown date announced | Not applicable |
gemini-2.5-flash-lite is gemini-3.1-flash-lite, not the newly released gemini-3.5-flash-lite. Jumping straight to the newest Lite model is a defensible choice, but it is your choice, not the documented upgrade path, and it is a two-generation jump rather than one. Plan and test it as such.gemini-3-flash-preview, there is no announced end date, but preview models are not something to build a roadmap on.Computer Use: four official pages, two answers
One capability question cannot be settled from documentation right now. Whether these models support Computer Use is stated inconsistently across Google's own material:
- The Gemini API model documentation marks Computer Use as supported (preview) for 3.6 Flash, while the enterprise platform page for the same model lists it as not supported.
- For 3.5 Flash-Lite, the model pages say it is not supported, while the launch announcement and the Gemini 3 developer guide say it works.
Four official pages, two contradictory answers, no way to resolve it by reading. If Computer Use is on your critical path, probe it on your own account and endpoint before you commit, and keep a fallback model wired up. This section will be updated with a tested answer and the date it was observed. Every other change in this guide is documented consistently; this one is not.
What this means if you are re-picking a provider this week
A migration you did not schedule has landed on your sprint, and the work is a day or two of careful editing rather than a weekend rewrite. Since you are already touching every call site, this is a natural moment to look at how the model reaches you at all.
Two things are worth checking while you are in there:
- Can you run the old and new models side by side during the cutover? Step 6 above requires it. If your setup makes running
gemini-3.5-flashandgemini-3.6-flashagainst the same task set awkward, that friction will be there for the next migration too, and there will be a next one: Google has said these rules apply to every model released from here on. - How fast does a new model become callable for you?
gemini-3.6-flashreached general availability with no preview suffix on day one. The gap between a model shipping and your code being able to call it is a cost you pay on every launch.
model string rather than a second SDK and a second set of credentials, and new models are available through the same endpoint you already use. If you want to see the current status of this specific model first, our Gemini 3.6 Flash release tracker has availability and model ID details, and the 3.6 Flash versus 3.5 Flash comparison covers whether the upgrade is worth doing at all, which is a different question from how to do it safely.gemini-3.6-flash they no longer do.FAQ
temperature, top_p and top_k are accepted and ignored, with no error and no warning. Google has stated that future model generations will return HTTP 400 for these parameters, so the silence is temporary, but for now a request carrying them looks completely healthy.thinking_level with values minimal, low, medium and high. Sending thinking_budget and thinking_level in the same request returns HTTP 400. The default is medium on 3.6 Flash and minimal on 3.5 Flash-Lite.gemini-3.1-flash-lite, not gemini-3.5-flash-lite, and gives a shutdown date of 16 October 2026. You can move to 3.5 Flash-Lite instead, but that is a two-generation jump and your own decision rather than the documented path.thinking_level switch, the prefill restriction, the FunctionResponse requirements and the removal of candidate_count all apply to gemini-3.5-flash-lite as well, and Google has said they apply to every model released after these two. The code changes are the same either way, so you can start the migration before you have settled which of the two you are moving to. That choice is a separate question, covered in our Gemini 3.6 Flash versus 3.5 Flash-Lite comparison.gemini-3.6-flash, with no preview suffix and no date stamp. If your deployment tooling expects a dated alias, it will fail at request time.Sources
- Using the latest Gemini models (Google AI for Developers): deprecated sampling parameters,
thinking_level,candidate_count, prefill restriction,FunctionResponserequirements, migration skill command - Gemini deprecations (Google AI for Developers): shutdown dates and recommended replacements
- Gemini API models (Google AI for Developers): model IDs, capability support matrix
- Gemini 3 developer guide (Google AI for Developers): Gemini 3 request behavior and capabilities
- Gemini 3.6 Flash on Gemini Enterprise Agent Platform (Google Cloud): enterprise capability listing and displayed parameter defaults
- Introducing Gemini 3.6 Flash, 3.5 Flash-Lite, and 3.5 Flash Cyber (Google): launch announcement and release date
- google-gemini/gemini-skills (GitHub): the official migration skill
- OpenRouter models endpoint (OpenRouter): gateway metadata listing
temperature,top_pandseedas supported parameters for both models, observed 2026-07-21 - EvoLink model catalog, Gemini 3.6 Flash release tracker, Gemini 3.6 Flash vs Gemini 3.5 Flash, Gemini 3.5 Flash vs Gemini 3 Flash Preview migration guide, Gemini 3 Pro deprecation guide, EvoLink API base URL


