Issue #378: Bug: no Gemini model in providers.json is usable on a new API key (2.5-flash / 2.5-flash-lite return 404 "no longer available to new users")

interviewstreet/hiring-agent · commit e0ece80 · investigation verified · 2026-10-17 · investigation cost $0.07

No open PR fixes this and merges clean

1 fix it but don't merge clean, 5 fix it partly. See the board below.

6/6
citations verified in code
194 → 18
open PRs shortlisted by cited lines
1 fix
0 merge clean · 5 partly
$0.07
investigation cost

How it breaks

The path is the model's reasoning. Each box is a citation checked against the code.

1providers.json:27 ✓
providers.json pins retired Gemini 2.5 model IDs
2providers.json:28 ✓
No -latest aliases; list is a static allowlist
3config.py:40 ✓
provider_for only checks name membership
4.env.example:3 ✓
Docs recommend the stale models
5models.py:483 ✓
First request to Google returns 404
where it shows

What's wrong

The Gemini model list in providers.json is a static allowlist of pinned model IDs, and two of them (gemini-2.5-flash, gemini-2.5-flash-lite) are retired for new API keys. config.provider_for() only checks that the name is in the list and that the key env var is set.
Show full explanationIt never checks that the model is available, so the failure only shows up as a 404 from Google at request time. .env.example and README.md recommend these pinned IDs, so a new contributor following the docs hits the failure. providers.json has no -latest aliases (gemini-flash-latest, gemini-flash-lite-latest), so nothing in the list tracks retirements. The 404 is confirmed from the code path only. Whether Google returns it can't be checked from the repo. The report's claim that the file ships five Gemini models is slightly off: it ships six, including gemini-3.8-flash. The 429 results are not provable from the repo and are quota or tier behaviour.
Model confidence: medium.

How to reproduce

  1. cp .env.example .env and set GEMINI_API_KEY to a newly created free-tier key
  2. Run: DEFAULT_MODEL=gemini-2.5-flash python score.py ./resume/sample.pdf --role software_engineering_intern
  3. config.provider_for('gemini-2.5-flash') resolves without error because the name is in providers.json
  4. The first POST to https://generativelanguage.googleapis.com/v1beta/openai/chat/completions returns 404 'no longer available to new users'
  5. Repeat with gemini-2.5-flash-lite for the same 404. Then try gemini-flash-latest after adding it to providers.json, which should return 200.

Evidence

Each citation was checked against the code at e0ece80.

providers.json2 citations
line 27
verified in code
"gemini-2.5-flash": { "temperature": 0.1, "top_p": 0.9 },

Retired-for-new-users model pinned in the Gemini allowlist, so config accepts it.

line 28
verified in code
"gemini-2.5-flash-lite": { "temperature": 0.1, "top_p": 0.9 },

Second retired model pinned in the allowlist. No -latest alias entries exist anywhere in the list.

config.py1 citation
line 40
verified in code
if model_name not in prov["models"]:

provider_for only checks membership in the static list. It does no availability check, so the stale model resolves fine.

models.py1 citation
line 483
verified in code
response = requests.post(url, json=body, headers=headers, timeout=300)

The first contact with Google's API happens at request time, where the 404 surfaces. 404 is not in the retry set, which covers only 429 and 5xx.

.env.example1 citation
line 3
verified in code
# Gemini examples: "gemini-2.5-pro", "gemini-2.5-flash"

Docs recommend the retired gemini-2.5-flash to new users.

README.md1 citation
line 189
verified in code
`gemini-2.5-pro`, or `gpt-6-luna`

The README's worked example uses a pinned 2.5 model. The 2.5-pro quota/429 behaviour is unverified from the repo.

Pull requests

Verdicts are judged from the diff, not run. Merge status is a real git check against e0ece80.

194open PRs
18change a cited line or mention the issue
6change the cause
0fix and merge clean
#402, #367, #379, #390, #407 and #456 all change the cause. Once one is merged, the others duplicate it.
Why each verdict

It deletes every dated Gemini pin from providers.json, replaces them with the gemini-flash-latest, gemini-flash-lite-latest and gemini-pro-latest aliases, and repoints .env.example and README at them, which removes both the retired entries and the stale docs.

Shortlisted because: mentions the issue, changes .env.example:3, changes README.md:189, changes providers.json:27, changes providers.json:28

It adds only gemini-flash-lite-latest while keeping the retired pins, and .env.example and README still recommend gemini-2.5-*.

Shortlisted because: changes providers.json:27, changes providers.json:28

It adds both -latest aliases and repoints .env.example and README at them, but it leaves the retired gemini-2.5-* pins in providers.json and adds no availability check.

Shortlisted because: mentions the issue, changes .env.example:3, changes README.md:189, changes providers.json:27, changes providers.json:28

It drops 2.0-* and 2.5-pro and updates .env.example, but it keeps the retired 2.5-flash and 2.5-flash-lite pins, adds only more dated pins and no -latest aliases, and leaves README still recommending the now-removed gemini-2.5-pro.

Shortlisted because: changes .env.example:3, changes providers.json:27, changes providers.json:28

It adds a single gemini-flash-latest alias, but the retired pins stay and the docs still point new users at the retired models.

Shortlisted because: changes providers.json:27, changes providers.json:28

It adds current 3.x pins, updates the README examples and surfaces the 404 message, but it keeps the retired 2.5 pins and adds no -latest aliases or availability check, so the list will go stale again.

Shortlisted because: changes README.md:189, changes providers.json:27, changes providers.json:28
12 PRs that don't fix itShow

It adds PDF validation and does not change the Gemini model list or the availability check.

Shortlisted because: changes .env.example:3

It adds .docx parsing; the only .env.example change comments out lines and still names gemini-2.5-*.

Shortlisted because: changes .env.example:3

It sets .env.example's DEFAULT_MODEL to the retired gemini-2.5-flash, which makes the doc problem worse.

Shortlisted because: changes .env.example:3

It adds Ollama cloud support and leaves the Gemini list and docs unchanged.

Shortlisted because: changes .env.example:3

It adds a litellm provider and leaves the stale Gemini pins and docs in place.

Shortlisted because: changes .env.example:3

It adds a Claude Agent SDK provider and does not touch the Gemini models or the docs that recommend them.

Shortlisted because: changes .env.example:3

It adds Anthropic docs and a README example of gemini-2.5-flash, which is a retired model, and does not touch the Gemini list.

Shortlisted because: changes .env.example:3, changes README.md:189

It adds a Groq provider entry and leaves the Gemini allowlist and docs unchanged.

Shortlisted because: changes providers.json:28

It adds an OrcaRouter provider and leaves the Gemini list and docs untouched.

Shortlisted because: changes .env.example:3, changes README.md:189

It is a security-analyst role PR; its one Gemini change adds a single pinned gemini-3.6-flash, which does not address the cause.

Shortlisted because: changes providers.json:27, changes providers.json:28

It adds a Bedrock transport and leaves the Gemini list, the retired pins, and the docs that recommend gemini-2.5-* unchanged.

Shortlisted because: changes .env.example:3, changes README.md:189, changes config.py:40

It adds more dated Gemini pins plus a benchmarking script, keeps the retired pins, and has no aliases or doc fixes.

Shortlisted because: changes providers.json:27, changes providers.json:28

What this packet does not prove

  • Citations are checked against the code. The explanation that links them, the order of the chain, and any claim about outside systems (APIs, libraries) are the model's reasoning and are not checked.
  • PR verdicts are judged from the diff, not run. No PR was applied or tested.
  • PRs were shortlisted because they change a cited line or mention the issue. A fix in another file, or a PR whose line numbers have drifted, is missed, so this is not proof that no other PR fixes it.