Requesting any gemini-<X.Y>-flash model with --model returns a successful response from gemini-3.5-flash, whatever version was asked for — including versions that do not exist. No error, no warning, empty stderr. The only signal is stats.models in --output-format json.
Adjacent to #28825 (entitlement-driven substitution under oauth-personal) and #28483 (3.6 missing from the selector), but distinct from both: this reproduces with an API key that does have access to the requested models, it is not entitlement-driven, and it fires on model ids that were never published.
Repro
export GEMINI_API_KEY=... # a key that CAN serve 3.6/3.7 — verified below
for M in gemini-3.7-flash gemini-3.6-flash gemini-3.2-flash gemini-1.0-flash \
gemini-3.9-flash gemini-4.2-flash gemini-3.5-flash-lite gemini-3.9-pro; do
printf '%-22s -> ' "$M"
HOME=$(mktemp -d) GEMINI_CLI_TRUST_WORKSPACE=true \
npx -y @google/gemini-cli@0.55.1 -m "$M" --output-format json -e none -p "say ok" 2>/dev/null \
| python3 -c 'import sys,json;d=sys.stdin.read();print(",".join(json.loads(d[d.index("{"):]).get("stats",{}).get("models",{}).keys()) or "(none)")'
done
Result
| Requested |
Served |
Exists at the API? |
gemini-3.7-flash |
gemini-3.5-flash |
✅ yes |
gemini-3.6-flash |
gemini-3.5-flash |
✅ yes |
gemini-3.2-flash |
gemini-3.5-flash |
❌ no |
gemini-1.0-flash |
gemini-3.5-flash |
❌ no |
gemini-3.9-flash |
gemini-3.5-flash |
❌ no |
gemini-4.2-flash |
gemini-3.5-flash |
❌ no |
gemini-3.5-flash-lite |
gemini-3.5-flash-lite |
✅ resolves exactly |
gemini-3.1-flash-lite |
gemini-3.1-flash-lite |
✅ resolves exactly |
gemini-3.9-pro |
errors |
❌ no — errors honestly |
gemini-3.9-flash-lite |
errors |
❌ no — errors honestly |
gemini-flash-latest |
gemini-3.7-flash |
✅ passes through |
Why this looks like a shape match, not an availability fallback
Three observations rule out the obvious explanations:
-
Not entitlement / availability. The same key serves gemini-3.7-flash and gemini-3.6-flash correctly over raw REST, with modelVersion echoing the request:
curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.7-flash:generateContent?key=$GEMINI_API_KEY" \
-H 'Content-Type: application/json' -d '{"contents":[{"parts":[{"text":"say ok"}]}]}' | jq -r .modelVersion
# gemini-3.7-flash
Both also appear in models.list for that key.
-
Not an unknown-model fallback. gemini-3.9-pro and gemini-3.9-flash-lite are equally unknown and equally nonexistent, and both pass through to the API and error honestly. Only the bare -flash shape is rewritten.
-
Not staleness. Identical on 0.55.1 (latest), 0.56.0-preview.1, and 0.56.0-nightly.20260817.g9a15c45fb.
The rewrite appears to key on the gemini-<number>.<number>-flash pattern specifically. gemini-flash-latest escapes it because it carries no <X.Y> segment.
Why it matters
Silently serving a different model than the one requested breaks anything that attributes results or cost to a model:
- Benchmarking is invalid without the operator knowing. A model comparison can attribute an entire run to a model that never executed. Nothing in the CLI's normal output contradicts it — you have to parse
stats.models from --output-format json to notice.
- Cost attribution is wrong, since flash tiers are not priced identically.
- A published model becomes unreachable by name. There is currently no way to request
gemini-3.6-flash or gemini-3.7-flash through the CLI. gemini-flash-latest reaches 3.7 today, but it is a floating alias — Google repointed it from gemini-3-flash-preview to gemini-3.5-flash in May 2026 — so it cannot be used to pin a version. The bare-flash family effectively has no pinnable path.
Expected behaviour
Either of these would be fine, and both are better than the current silence:
- Pass the requested id through and let the API decide (which is what already happens for
-pro and -flash-lite shapes, and which errors honestly for genuinely bad ids); or
- If the CLI intends to substitute, say so on stderr —
requested X, serving Y — and let --model refuse rather than silently downgrade.
Environment
@google/gemini-cli 0.55.1, 0.56.0-preview.1, 0.56.0-nightly.20260817.g9a15c45fb — all identical
- Auth:
GEMINI_API_KEY (Gemini API, not Vertex, not OAuth)
- macOS 15.3, Node 23.7.0
- Isolated
HOME per invocation, so no local settings.json is involved. Adding a modelConfigs.resolution entry mapping gemini-3.7-flash to itself does not change the outcome.
Requesting any
gemini-<X.Y>-flashmodel with--modelreturns a successful response fromgemini-3.5-flash, whatever version was asked for — including versions that do not exist. No error, no warning, empty stderr. The only signal isstats.modelsin--output-format json.Adjacent to #28825 (entitlement-driven substitution under
oauth-personal) and #28483 (3.6 missing from the selector), but distinct from both: this reproduces with an API key that does have access to the requested models, it is not entitlement-driven, and it fires on model ids that were never published.Repro
Result
gemini-3.7-flashgemini-3.5-flashgemini-3.6-flashgemini-3.5-flashgemini-3.2-flashgemini-3.5-flashgemini-1.0-flashgemini-3.5-flashgemini-3.9-flashgemini-3.5-flashgemini-4.2-flashgemini-3.5-flashgemini-3.5-flash-litegemini-3.5-flash-litegemini-3.1-flash-litegemini-3.1-flash-litegemini-3.9-progemini-3.9-flash-litegemini-flash-latestgemini-3.7-flashWhy this looks like a shape match, not an availability fallback
Three observations rule out the obvious explanations:
Not entitlement / availability. The same key serves
gemini-3.7-flashandgemini-3.6-flashcorrectly over raw REST, withmodelVersionechoing the request:Both also appear in
models.listfor that key.Not an unknown-model fallback.
gemini-3.9-proandgemini-3.9-flash-liteare equally unknown and equally nonexistent, and both pass through to the API and error honestly. Only the bare-flashshape is rewritten.Not staleness. Identical on
0.55.1(latest),0.56.0-preview.1, and0.56.0-nightly.20260817.g9a15c45fb.The rewrite appears to key on the
gemini-<number>.<number>-flashpattern specifically.gemini-flash-latestescapes it because it carries no<X.Y>segment.Why it matters
Silently serving a different model than the one requested breaks anything that attributes results or cost to a model:
stats.modelsfrom--output-format jsonto notice.gemini-3.6-flashorgemini-3.7-flashthrough the CLI.gemini-flash-latestreaches 3.7 today, but it is a floating alias — Google repointed it fromgemini-3-flash-previewtogemini-3.5-flashin May 2026 — so it cannot be used to pin a version. The bare-flash family effectively has no pinnable path.Expected behaviour
Either of these would be fine, and both are better than the current silence:
-proand-flash-liteshapes, and which errors honestly for genuinely bad ids); orrequested X, serving Y— and let--modelrefuse rather than silently downgrade.Environment
@google/gemini-cli0.55.1,0.56.0-preview.1,0.56.0-nightly.20260817.g9a15c45fb— all identicalGEMINI_API_KEY(Gemini API, not Vertex, not OAuth)HOMEper invocation, so no localsettings.jsonis involved. Adding amodelConfigs.resolutionentry mappinggemini-3.7-flashto itself does not change the outcome.