Skip to content

fix(desktop): auto-recover dangling model refs on provider removal#3249

Open
SivanCola wants to merge 3 commits into
esengine:main-v2from
SivanCola:fix/desktop-model-dangling-recovery
Open

fix(desktop): auto-recover dangling model refs on provider removal#3249
SivanCola wants to merge 3 commits into
esengine:main-v2from
SivanCola:fix/desktop-model-dangling-recovery

Conversation

@SivanCola
Copy link
Copy Markdown
Collaborator

Summary

When a provider is deleted or replaced in desktop settings, tabs with stale model refs (default_model, planner_model, tab.model) would fail at startup with unknown model "deepseek-flash" (configured: glm-4v) errors. This adds automatic fallback to the first configured provider, fixes all open tab refs on provider deletion, and shows actionable recovery UI.

Key changes

  • ResolveModelWithFallback — resolves a model ref with automatic fallback to the first configured provider when the ref is stale. Only picks providers with a valid API key.
  • RemoveProvider auto-migration — detects both "name" and "name/model" refs in default_model and planner_model. Auto-migrates to fallback instead of blocking. Only refuses when no other configured provider exists.
  • buildTabController / rebuild / currentProviderEntryForTab — all use fallback resolution so stale refs don't crash the session.
  • DeleteProvider tab sync — traverses all open tabs and fixes model refs targeting the deleted provider. Always calls rebuild() and propagates errors.
  • Settings health diagnosticsSettingsView now exposes currentModel, currentModelValid, defaultModelValid, plannerModelValid, modelWarning.
  • Sync methodsSyncActiveTabModelToDefault() and SyncAllTabModelsToDefault() Wails bindings with frontend buttons.
  • Startup error recovery UI — structured error fields (startupErrCode, startupErrModel, startupErrConfigured, startupRecoveryModel). Banner shows "Switch to X" button, "Open model settings" shortcut, and expandable error details.
  • SetModelForTab fix — now clears tab.StartupErr, sets tab.Ready = true, and emits agent:ready so the frontend refreshes Meta/Balance/Effort after model recovery.

Risk mitigations verified

  1. LoadForRoot loads global credentials via loadDotEnvForRoot before ResolveModelWithFallback is called — Configured() correctly detects keyed providers.
  2. CLI does not call config.RemoveProvider — the auto-migration semantic is desktop-only in practice.
  3. DeleteProvider correctly propagates rebuild() errors (no _ = a.rebuild()).
  4. StartupErrorBanner uses useController.setModel which dispatches Meta/Context/Effort refreshes after recovery.

Test plan

go test ./internal/config/...     # 15 new tests + all existing pass
cd desktop && go test ./...       # existing tests pass
cd desktop/frontend && npm run build  # type check passes (pre-existing Wails errors only)

…ers are removed

When a provider is deleted or replaced in desktop settings, tabs with
stale model refs (default_model, planner_model, tab.model) would fail
at startup with "unknown model" errors. This adds automatic fallback
to the first configured provider, fixes all open tab refs on provider
deletion, and shows actionable recovery UI when no model is available.

- Add ResolveModelWithFallback: resolve model ref with automatic
  fallback to the first configured provider
- Fix RemoveProvider: detect "provider/model" refs in default_model
  and planner_model, auto-migrate instead of blocking
- Fix buildTabController / rebuild / currentProviderEntryForTab to use
  fallback resolution
- Sync all tab model refs when a provider is deleted, rebuild active tab
- Add model health diagnostics to SettingsView (validity flags, warnings)
- Add SyncActiveTabModelToDefault / SyncAllTabModelsToDefault methods
- Structured startup error fields for actionable recovery UI
- Startup error banner with "Switch to X" button and settings shortcut
@github-actions github-actions Bot added the v2 Go rewrite (1.x) — main-v2 branch, active development label Jun 5, 2026
@SivanCola SivanCola marked this pull request as ready for review June 5, 2026 15:28
@SivanCola SivanCola requested a review from esengine as a code owner June 5, 2026 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant