Fix cross-provider key name collision in fallback lookup#3570
Conversation
📝 WalkthroughWalkthroughScopes the fallback lookup in UpdateProvidersConfig to include provider_id when resolving keys by name, and adds a test ensuring providers with identical key names keep distinct key rows and values. ChangesConfiguration key lookup fix
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
|
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Confidence Score: 5/5Safe to merge — the change is a targeted one-liner that corrects a clearly wrong query predicate, and the new regression test directly validates the fixed behavior. The fix is minimal and precisely scoped: one additional AND provider_id = ? bind parameter in a single GORM query. The surrounding logic is unchanged, the new parameter (dbProvider.ID) is already in scope and correctly reflects the current provider being iterated, and the regression test confirms both providers keep their own keys after the sync. No files require special attention. Important Files Changed
Reviews (2): Last reviewed commit: "fix(configstore): scope UpdateProvidersC..." | Re-trigger Greptile |
e3570ac to
d37e33f
Compare
303df0f to
1d39a23
Compare
d37e33f to
f0ef5c9
Compare
1d39a23 to
d472742
Compare
|
As discussed in Slack, this change has been marked as good to have and moved to the backlog for now. While scoping API key name lookups by In the meantime, this is being addressed via #3574, which improves the user-facing error message to clearly communicate that API key names must be unique across providers. |

Summary
Fixes the startup sync (
UpdateProvidersConfig) to scope key name lookups byprovider_id. Previously, when the sync encountered a key whose UUID didn't match any existing row, it fell back to a global name lookup (Where("name = ?")) that could match a key belonging to a different provider, silently overwriting it.The fix adds
AND provider_id = ?to the name fallback query, ensuring it only matches keys within the same provider. This aligns with the new composite unique index(provider_id, name)introduced in the sibling PR, where key names are unique per-provider rather than globally.Changes
UpdateProvidersConfigfromWhere("name = ?")(global) toWhere("name = ? AND provider_id = ?")(scoped to the current provider)TestUpdateProvidersConfig_CrossProviderSameKeyNameregression test that creates two providers each with a key named"default"and verifies both keys are preserved after the syncType of change
Affected areas
How to test
The regression test directly validates the fix:
On the old (buggy) code, this test fails with
"[] should have 1 item(s), but has 0"for the first provider. On the fixed code, it passes.All existing tests still pass:
Screenshots/Recordings
N/A — No UI changes.
Breaking changes
The fix only changes the startup sync behavior from "wrong" (global lookup, data-corrupting) to "right" (scoped lookup). No API or schema changes.
Related issues
Fixes the root cause of the HTTP 500 error on provider update: the startup sync was corrupting key ownership between providers, and the subsequent single-provider update couldn't create a new key because the name was already taken globally.
Security considerations
None.
Checklist
docs/contributing/README.mdand followed the guidelinesWhy this matters
Before this change, API key names had to be unique across all providers. If you had two providers - say OpenAI and Anthropic - they could not both have an API key named "default". The second one would collide with the first and fail with an error.
After this change, key names only need to be unique per provider. Each provider can independently have a "default" key (or any other name) without conflict.