fix: UI language reverts to English after a second save in Settings#105
Merged
nashsu merged 1 commit intonashsu:mainfrom May 1, 2026
Merged
Conversation
handleSave calls multiple zustand setters (setLlmConfig, setEmbeddingConfig, ...) BEFORE it calls i18n.changeLanguage at the end. Each setter creates a new store object, which re-fires the resync useEffect — and that effect was rebuilding the entire draft from i18n.language, which is still the OLD language at this point. Net effect: after the first save (e.g. en→zh) succeeded, the component-state draft.uiLanguage had been silently rewritten back to "en" by the mid-save resync. The next save (e.g. editing the Embedding section) then sees draft.uiLanguage="en" vs i18n.language="zh", enters the change-language branch, and reverts the UI to English. Fix: when the resync effect rebuilds the draft, keep the current draft.uiLanguage via a functional setState — uiLanguage only changes via the Interface section's setDraft, never out-of-band, so preserving it across store-driven resyncs is correct.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #104.
Problem
After switching the UI language to Chinese in Settings → Interface and saving, opening another draft-bound section (Embedding / Multimodal / Web Search / Network / Output), editing any field, and clicking Save again silently flips the entire UI back to English and persists
language=ento the store. Reproduces 100% onmain(v0.4.5).Root cause
SettingsViewhas a resyncuseEffectthat rebuilds the whole draft whenever any of the store slices change, and re-readsi18n.languagewhile doing so.handleSavecalls multiple zustand setters before it finally callsi18n.changeLanguageat the end — and eachawaitbetween setters lets React commit, which fires the resync effect mid-save. At that pointi18n.languageis still the OLD value, so the effect silently rewritesdraft.uiLanguageback to the old language.The first save still works because
handleSavecloses over its own snapshot ofdraft(with the newuiLanguage), soif (draft.uiLanguage !== i18n.language)still takes the change-language branch successfully. But after that save:i18n.language === "zh"✅draft.uiLanguage === "en"(clobbered by the mid-save resync)The next save reads the stale
draft.uiLanguage = "en", hits the sameifcondition with"en" !== "zh", and helpfully callschangeLanguage("en")+saveLanguage("en")— reverting and persisting the language flip the user never asked for.Fix
One-line change in the resync effect: keep the current
draft.uiLanguagevia a functional setState instead of re-readingi18n.language.uiLanguageis only ever written by the Interface section'ssetDraft, never out-of-band, so preserving it across store-driven resyncs is correct.useEffect(() => { - setDraftState( + setDraftState((prev) => initialDraft( llmConfig, searchApiConfig, embeddingConfig, multimodalConfig, outputLanguage, proxyConfig, maxHistoryMessages, - i18n.language, + prev.uiLanguage, ), ); }, [...]);Plus a code comment explaining why this is intentional, so the next person doesn't "fix" it back.
Verification
Manual repro on
main:draft.uiLanguageactually became"en"🐛After this patch, step 2 keeps the UI in Chinese, and
language=zhstays persisted.The fix doesn't change any other section's behavior:
prev.uiLanguageat that point is the value used to mount the panel (which equalsi18n.languageat mount time), so behavior is unchanged for that scenario.