dgtlmoon / dgtlmoon/changedetection.io

Gemini 3.x models fail with 400 INVALID_ARGUMENT: deprecated temperature and thinkingConfig.thinkingBudget are still sent in generationConfig

Open
#4,283 1 comment 0 reactions 1 assignee Claimed by @dgtlmoon View on GitHub
LLM AI triage
Dominant language
Python
Stars
34.3k
Forks
2.1k
Avg merge
22h 52m
Merged PRs (30d)
70

Description

## Describe the bug

Every LLM operation (AI change summary and AI change intent) fails when the configured model is from the Gemini 3.x lite family. changedetection.io sends temperature and thinkingConfig.thinkingBudget in generationConfig; both are deprecated on Gemini 3.x, and Google rejects the request with a bare 400 INVALID_ARGUMENT and no details field.

The failure is close to silent. The settings-page connection test passes, the LLM Usage tab simply stays empty, and notifications continue to fire normally — but _llm_result falls back to {"important": true, "summary": ""}. Because important: true is also the value for a genuine positive verdict, a total LLM outage is indistinguishable from working intent-matching when read from the notification alone. I ran with this misconfiguration for some time believing the intent filter was working and simply being permissive.

## Version

0.55.8

## How did you install?

Docker (`ghcr.io/dgtlmoon/changedetection.io:latest`), arm64 on a Raspberry Pi 5.

## To Reproduce

Steps to reproduce the behavior:

Go to Settings → LLM
1. Enter a Google AI Studio API key and set the model to `gemini/gemini-3.5-flash-lite`
2. Click the connection test — it passes
3. Open any watch that already has two or more snapshots, go to the diff page
4. Click the "Summary" button
5. See error: Request contains an invalid argument..

No particular URL is required — this reproduces on any watch with history, because the fault is in the request changedetection.io builds rather than in the page being watched. Share link included anyway per the template: https://changedetection.io/share/ZheMgM2rBIoa

Log output
```
litellm.BadRequestError: GeminiException BadRequestError - {
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT"
}
}
changedetectionio.blueprint.ui.diff:diff_llm_summary:313 - LLM summary generation failed for
```
With `LITELLM_LOG=DEBUG`, the outbound request is:
```
POST https://generativelanguage.googleapis.com/v1alpha/models/gemini-3.5-flash-lite:generateContent?key=*****

{
"contents": [...],
"system_instruction": {...},
"generationConfig": {
"temperature": 0,
"max_output_tokens": 400,
"thinkingConfig": {"thinkingBudget": 0}
}
}
```
Expected behavior

The LLM summary should generate. Specifically, either:

`temperature` and `thinkingConfig` should be omitted for Gemini 3.x lite models — thinking_level is the documented replacement for `thinkingBudget` — or
the existing strip-and-retry path should catch this. #4241 ("LLM: strip sampling params and retry when the model rejects them", shipped in 0.55.8) does not appear to fire here, possibly because it strips sampling params but not thinkingConfig, or because this error shape doesn't trigger the retry.

Separately, a failed LLM call should be distinguishable from a positive verdict rather than falling back to important: true with an empty summary.

Screenshots

N/A — the failure is in the API request, fully captured in the log output above.

Desktop (please complete the following information):

OS: Raspbian 6.3
Browser: Firefox
Version: 153

(Not browser-dependent — the failure is server-side in the outbound API call.)

Smartphone (please complete the following information):

N/A

Additional context

Root cause is Google's Gemini 3.x migration requirements. From the official migration guide:

Remove temperature, top_p, top_k from your config (no longer recommended). Replace thinking_budget with thinking_level.

https://ai.google.dev/gemini-api/docs/whats-new-gemini-3.5

Confirmed outside changedetection.io. This succeeds:

```bash
curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash-lite:generateContent?key=$KEY" \
-H 'Content-Type: application/json' \
-d '{"contents":[{"role":"user","parts":[{"text":"say hi"}]}]}'
```
This fails with the same 400 INVALID_ARGUMENT:

```bash
curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash-lite:generateContent?key=$KEY" \
-H 'Content-Type: application/json' \
-d '{"contents":[{"role":"user","parts":[{"text":"say hi"}]}],
"generationConfig":{"temperature":0,"thinkingConfig":{"thinkingBudget":0}}}'
```
Workaround: set the model to gemini/gemini-2.5-flash, which still accepts both parameters. Everything then works as documented.

Possibly related: #4224 — reporter on 0.55.7 with llm_summary and _llm_change_summary both empty while the notification still fired. Same signature as this bug before I switched models. Worth checking whether that reporter was also on a Gemini 3.x model.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.