Problem
After using auto-fetch to get available models from a provider and then manually deleting unwanted models, the deleted models reappear every time the user opens the Settings panel (or restarts and opens Settings).
Root Cause
File: desktop/frontend/src/components/SettingsPanel.tsx, lines 666–692
The auto-refresh useEffect fires every time the "usage" subtab renders and unconditionally replaces the user's curated model list with the full API response:
useEffect(() => {
if (subtab !== "usage") return;
// ...
void backgroundApply(async () => {
for (const { provider } of candidates) {
const fetched = await app.FetchProviderModels(provider);
// ↓↓↓ ALWAYS overwrites with full fetched list ↓↓↓
await app.SaveProvider({ ...provider, models: fetched, default: currentDefault });
}
});
}, [backgroundApply, s.providers, subtab, t]);
Exact bug sequence
- User adds a provider → auto-fetch saves all models ✅
- User edits provider, removes unwanted models, saves → curated list written to
config.toml ✅
- User restarts app → config loads correctly with curated list (boot path does NOT fetch) ✅
- User opens Settings → "usage" subtab →
useEffect fires, autoRefreshKeyRef has reset after restart → fetches ALL models from API → overwrites curated list via SaveProvider ❌
The autoRefreshKeyRef guard only prevents re-fetching within the same session. After any restart or config reload, the ref resets and auto-fetch runs again.
Additional auto-fetch paths with the same issue
saveKeyEnvAndAutoRefresh (lines 1064–1097): After saving an API key, immediately fetches and overwrites.
refreshModels (lines 1024–1056): Manual "Refresh models" button also does a full replacement (this one is arguably intentional).
Suggested Fix
Option A — Only merge new models (never remove):
const merged = [...new Set([...provider.models, ...fetched])];
// Only save if there are actually new models
if (!sameStringLists(provider.models, merged)) {
await app.SaveProvider({ ...provider, models: merged, default: currentDefault });
}
Option B — Track user curation with a flag:
Add a modelsUserEdited: boolean field to ProviderView/ProviderEntry. When the user manually edits the model list, set it to true. Auto-refresh skips providers where modelsUserEdited === true.
Option C — Remove auto-refresh, keep manual only:
Remove the auto-refresh useEffect entirely. Users explicitly click "Refresh models" when they want to discover new ones. This is the simplest fix and avoids the issue entirely.
Problem
After using auto-fetch to get available models from a provider and then manually deleting unwanted models, the deleted models reappear every time the user opens the Settings panel (or restarts and opens Settings).
Root Cause
File:
desktop/frontend/src/components/SettingsPanel.tsx, lines 666–692The auto-refresh
useEffectfires every time the "usage" subtab renders and unconditionally replaces the user's curated model list with the full API response:Exact bug sequence
config.toml✅useEffectfires,autoRefreshKeyRefhas reset after restart → fetches ALL models from API → overwrites curated list viaSaveProvider❌The
autoRefreshKeyRefguard only prevents re-fetching within the same session. After any restart or config reload, the ref resets and auto-fetch runs again.Additional auto-fetch paths with the same issue
saveKeyEnvAndAutoRefresh(lines 1064–1097): After saving an API key, immediately fetches and overwrites.refreshModels(lines 1024–1056): Manual "Refresh models" button also does a full replacement (this one is arguably intentional).Suggested Fix
Option A — Only merge new models (never remove):
Option B — Track user curation with a flag:
Add a
modelsUserEdited: booleanfield toProviderView/ProviderEntry. When the user manually edits the model list, set it totrue. Auto-refresh skips providers wheremodelsUserEdited === true.Option C — Remove auto-refresh, keep manual only:
Remove the auto-refresh
useEffectentirely. Users explicitly click "Refresh models" when they want to discover new ones. This is the simplest fix and avoids the issue entirely.