Skip to content

feat(proxy): say when a stored setting is ignored because the config file owns it - #41985

Merged
yuneng-berri merged 1 commit into
mainfrom
litellm_config_shadows_db_warning
Sep 19, 2026
Merged

yuneng-berri merged 1 commit into
mainfrom
litellm_config_shadows_db_warning

Conversation

@yuneng-berri

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • The config file winning over the database was completely silent
  • A stored value stops applying with nothing said at boot
  • The refusal on a later write never mentioned the stored value

How it solves it:

  • Startup warns once per key whose stored value is being ignored
  • The write refusal carries the same sentence as the log line
  • Both name the key and say what to do about it

User Flow

Before: an admin who set an allowlist in the UI, then later pinned it in the config file, has no way to learn their stored value stopped applying

  1. They add two IPs through http://litellm-domain/ui/?page=settings, which stores them in the database
  2. Later they pin general_settings.allowed_ips in the config file with a narrower list and restart
  3. Startup logs nothing about the two lists disagreeing
  4. GET http://litellm-domain/get/allowed_ips returns the file's list, and the stored one is simply gone from view
  5. They send POST http://litellm-domain/add/allowed_ip and get a 400 saying the key is set in the config file, with no hint that a stored value already exists and is being ignored

After: the same admin is told at startup, and again the moment a write is refused

  1. They do the same two steps
  2. Startup logs a warning naming general_settings.allowed_ips, saying the value stored in the database is ignored and will never be applied, and how to change that
  3. GET http://litellm-domain/get/allowed_ips returns the file's list, as before
  4. They send the same POST and get a 400 carrying that same sentence, plus stored_database_value_ignored: true
  5. Nothing about which list applies has changed, but the admin can now see why

Relevant issues

Affected release

Linear ticket

Pre-Submission checklist

  • I have added meaningful tests
  • The handful of test files covering my change pass locally, e.g. uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*, make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more
  • My PR passes all required CI/CD checks (e.g., lint, schema.d.ts sync check, etc.)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Screenshots / Proof of Fix

Shared setup, identical on both sides. A local proxy whose config file pins a two-IP allowlist, with a database row already storing a wider one, so the file and the database disagree on the same key.

general_settings:
  master_key: sk-1234
  allowed_ips: ["127.0.0.1", "10.0.0.7"]
psql "$DATABASE_URL" -c "insert into \"LiteLLM_Config\" (param_name, param_value) values ('general_settings', '{\"allowed_ips\": [\"127.0.0.1\", \"10.0.0.7\", \"203.0.113.5\"]}'::jsonb);"

Before (209a780)

  1. What the proxy said at startup about the disagreement
grep -iE 'ignored|never be applied' litellm.log
(nothing logged)
  1. The allowlist the proxy actually serves
curl -s http://127.0.0.1:50339/get/allowed_ips -H 'Authorization: Bearer sk-1234'
{"data":["127.0.0.1","10.0.0.7"]}
  1. Try to add an IP
curl -s -w ' <- HTTP %{http_code}\n' -X POST http://127.0.0.1:50339/add/allowed_ip \
  -H 'Authorization: Bearer sk-1234' -H 'content-type: application/json' \
  -d '{"ip": "198.51.100.9"}'
{"detail":{"error":"general_settings key 'allowed_ips' is set in the config file and cannot be changed here","keys":["allowed_ips"],"section":"general_settings","resolution":"edit the config file to change it, or remove it from the file to let the database own it"}} <- HTTP 400

After (7353b77)

  1. What the proxy said at startup about the disagreement
grep -iE 'ignored|never be applied' litellm.log
LiteLLM Proxy:WARNING: proxy_server.py:7450 - general_settings.allowed_ips is set in the config file, so the config file owns it and it cannot be changed here. The value stored in the database for it is ignored and will never be applied. Edit the config file to change it, or remove it from the file to let the database own it.
  1. The allowlist the proxy actually serves
curl -s http://127.0.0.1:50339/get/allowed_ips -H 'Authorization: Bearer sk-1234'
{"data":["127.0.0.1","10.0.0.7"]}
  1. Try to add an IP
curl -s -w ' <- HTTP %{http_code}\n' -X POST http://127.0.0.1:50339/add/allowed_ip \
  -H 'Authorization: Bearer sk-1234' -H 'content-type: application/json' \
  -d '{"ip": "198.51.100.9"}'
{"detail":{"error":"general_settings.allowed_ips is set in the config file, so the config file owns it and it cannot be changed here. The value stored in the database for it is ignored and will never be applied. Edit the config file to change it, or remove it from the file to let the database own it.","keys":["allowed_ips"],"section":"general_settings","stored_database_value_ignored":true}} <- HTTP 400

Type

🆕 New Feature
🐛 Bug Fix

Caveats (if any)

Medium

  • The warning fires only when the two values differ
    • A stored value equal to the file's is a deliberate promotion, so warning on it would be noise
  • Precedence stays per key, not per section
    • A file that pins one key still lets the database own every other key in that section

Low

  • The warning names keys, never values, so nothing sensitive reaches the log
  • The 400 says a stored value exists but does not echo it, for the same reason
  • Repeated config loads warn once per key, not once per load

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

…file owns it

The config file winning over the database was silent. An admin who had set
a value through the UI and later pinned the same key in the file saw their
stored value quietly stop applying, with nothing said at boot and nothing
said when a later write was refused.

Startup now warns once per key whose stored value differs from the file's,
naming the key and what to do about it. The refusal raised on a write to a
config-owned key carries the same sentence, so the log and the 400 read
identically, and both call out that a stored value exists and will never be
applied. The /config/update refusal gained the same detail.

Keys the file does not declare are untouched: the database still owns them,
and a stored value equal to the file's is not worth a warning.
@yuneng-berri
yuneng-berri requested a review from a team September 19, 2026 17:22
@codspeed

codspeed Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_config_shadows_db_warning (7353b77) with main (209a780)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (bd82d73) during the generation of this report, so 209a780 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

@greptile-apps

greptile-apps Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge, with config precedence unchanged and the new diagnostics limited to genuine differing stored values

Summary

This PR adds diagnostics for database settings shadowed by config-file ownership. It tracks differing stored values, logs each active conflict once per key, and includes the same explanation in rejected administrative writes without exposing stored values

Reviews (1) · Last reviewed commit: "feat(proxy): say when a stored setting i..."

@codecov

codecov Bot commented Sep 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@yuneng-berri
yuneng-berri merged commit d0f60fc into main Sep 19, 2026
88 checks passed
@yuneng-berri
yuneng-berri deleted the litellm_config_shadows_db_warning branch September 19, 2026 17:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants