diff --git a/Issue_29213.md b/Issue_29213.md new file mode 100644 index 00000000000..e50c6e0a838 --- /dev/null +++ b/Issue_29213.md @@ -0,0 +1,105 @@ +# Unexpected model resolution: gemini-2.5-flash is mapped to gemini-3.5-flash + +### What happened? + +## `--model gemini-2.5-flash` is resolved to `gemini-3.5-flash` when using Vertex AI + +## Summary + +When invoking Gemini CLI with `--model gemini-2.5-flash`, the CLI appears to +resolve the request to `gemini-3.5-flash` instead of the specified model. + +As a result, the request fails because my Vertex AI project does not have access +to `gemini-3.5-flash`. + +## Environment + +- Gemini CLI version: **0.58.0** +- Also reproduced on: **0.54.0** +- Node.js: **v24.13.0** +- Authentication: **Vertex AI (ADC)** + +## Reproduction + +Run: + +```bash +echo "hello" | gemini \ + --model gemini-2.5-flash \ + --prompt "" +``` + +## Actual Behavior + +The request fails with the following error: + +```text +Error when talking to Gemini API + +ModelNotFoundError: Publisher model +`projects/.../locations/us-central1/publishers/google/models/gemini-3.5-flash` +was not found or your project does not have access to it. +``` + +Although `gemini-2.5-flash` was specified, the CLI appears to send the request +to `gemini-3.5-flash`. + +## Expected Behavior + +The CLI should send the request to `gemini-2.5-flash` when it is explicitly +specified with: + +```bash +--model gemini-2.5-flash +``` + +It should not resolve or rewrite the model name to `gemini-3.5-flash`. + +## Additional Information + +Using the same environment and authentication, the following command works as +expected: + +```bash +echo "hello" | gemini \ + --model gemini-2.5-pro \ + --prompt "" +``` + +### What did you expect to happen? + +It should not resolve or rewrite the model name to `gemini-3.5-flash`. + +### Client information + +
+Client Information + +Run on Linux + +Run `gemini` to enter the interactive CLI, then run the `/about` command. + +```console +> /about +│ About Gemini CLI │ +│ │ +│ CLI Version 0.54.0 │ +│ Git Commit a74b483d1 │ +│ Model gemini-2.5-pro │ +│ Sandbox no sandbox │ +│ OS linux │ +│ Auth Method vertex-ai │ +│ GCP Project *** │ +│ IDE Client VS Code │ +│ +``` + +
+ +### Login information + +_No response_ + +### Anything else we need to know? + +_No response_ diff --git a/packages/core/src/config/defaultModelConfigs.ts b/packages/core/src/config/defaultModelConfigs.ts index 056b91b351d..0fba322e8b8 100644 --- a/packages/core/src/config/defaultModelConfigs.ts +++ b/packages/core/src/config/defaultModelConfigs.ts @@ -492,12 +492,6 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = { }, ], }, - 'gemini-2.5-flash': { - default: 'gemini-2.5-flash', - contexts: [ - { condition: { useGemini3_5Flash: true }, target: 'gemini-3.5-flash' }, - ], - }, 'gemini-3-pro-preview': { default: 'gemini-3-pro-preview', contexts: [ diff --git a/packages/core/src/config/models.test.ts b/packages/core/src/config/models.test.ts index 63185f77614..8e6a1c2fa89 100644 --- a/packages/core/src/config/models.test.ts +++ b/packages/core/src/config/models.test.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, afterEach } from 'vitest'; import { resolveModel, resolveClassifierModel, @@ -19,6 +19,7 @@ import { DEFAULT_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_3_5_FLASH_MODEL, DEFAULT_GEMINI_FLASH_LITE_MODEL, + setFlashModels, supportsMultimodalFunctionResponse, GEMINI_MODEL_ALIAS_PRO, GEMINI_MODEL_ALIAS_FLASH, @@ -787,7 +788,25 @@ describe('resolveModel Gemini 3.5 Flash GA', () => { ).toBe(PREVIEW_GEMINI_FLASH_MODEL); }); - it('should resolve all but preview flash models to gemini-3.5-flash when useGemini3_5Flash is true (dynamic)', () => { + describe('explicit --model gemini-2.5-flash (issue #29213)', () => { + afterEach(() => { + // Restore the module-level defaults mutated by setFlashModels(). + setFlashModels('gemini-3-flash-preview', 'gemini-2.5-flash'); + }); + + it('should not rewrite an explicitly requested gemini-2.5-flash to gemini-3.5-flash once GA rollout has flipped the default flash pointer (legacy)', () => { + // Simulates hasGemini35FlashGAAccess() mutating the default/preview + // flash pointers once GA is available for the user's backend (e.g. + // Vertex AI), as happens before routing an explicit --model flag. + setFlashModels('gemini-3.5-flash', 'gemini-3.5-flash'); + + expect( + resolveModel('gemini-2.5-flash', false, false, true, undefined, true), + ).toBe('gemini-2.5-flash'); + }); + }); + + it('should resolve the flash alias to gemini-3.5-flash when useGemini3_5Flash is true, but leave explicitly requested concrete flash models untouched (dynamic)', () => { const mockDynamicConfig = { getExperimentalDynamicModelConfiguration: () => true, modelConfigService, @@ -803,16 +822,19 @@ describe('resolveModel Gemini 3.5 Flash GA', () => { true, ), ).toBe('gemini-3.5-flash'); + // An explicitly requested, pinned model ID must not be silently + // rewritten to a different model, even when the 3.5 flash GA alias + // upgrade is active. See https://github.com/google-gemini/gemini-cli/issues/29213 expect( resolveModel( - DEFAULT_GEMINI_FLASH_MODEL, + 'gemini-2.5-flash', false, false, true, mockDynamicConfig, true, ), - ).toBe('gemini-3.5-flash'); + ).toBe('gemini-2.5-flash'); expect( resolveModel( PREVIEW_GEMINI_FLASH_MODEL, diff --git a/packages/core/src/config/models.ts b/packages/core/src/config/models.ts index dd6506b837c..d0bfaef9e06 100644 --- a/packages/core/src/config/models.ts +++ b/packages/core/src/config/models.ts @@ -260,13 +260,14 @@ export function resolveModel( } function isFlashModel(model: string): boolean { + // No `endsWith('flash')` catch-all: that would also match explicitly + // pinned model IDs like 'gemini-2.5-flash' and silently upgrade them. return ( model === DEFAULT_GEMINI_FLASH_MODEL || model === PREVIEW_GEMINI_FLASH_MODEL || model === DEFAULT_GEMINI_3_5_FLASH_MODEL || model === SECONDARY_GEMINI_3_5_FLASH_MODEL || - model === 'flash' || - model.endsWith('flash') + model === 'flash' ); }