Repository navigation
fix(desktop): one unreadable value in desktop-settings.json no longer resets every desktop setting - #28682
fix(desktop): one unreadable value in desktop-settings.json no longer resets every desktop setting#28682only21mil wants to merge 3 commits into
Conversation
… resets every desktop setting Co-Authored-By: Claude Opus 5.5 <[email protected]>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Unreadable desktop settings now fall back individually, preserving other saved preferences. Existing defaults and validation remain unchanged, with no new operational behavior introduced. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
|
Note Written by Verified in a real dev environmentverified head reproduced on {"localEnvironmentEnabled":false,"updateChannel":"beta","wslOnly":"yes","mainWindowBounds":{"x":120,"y":80,"width":1280,"height":900}}
the development harness requests relaunch by exiting with code 75; i relaunched the identical electron command after each restart request. session d-bus was isolated to avoid configuring the vm's keyring.
before, main: after, this head with the same input: Not verifiedmacos, windows/wsl, native ios/android, packaged installers, tailscale exposure, remote/relay connections, and update downloads were not exercised on this linux vm. linux keyring integration was not exercised. invalid update-channel and wsl values were hand-written to reproduce the reported file corruption; project, thread, and provider data were created through the real app. |
… load and save Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Note 🤖 Opus 5.5 replying on behalf of Victor. /recheck-vouch |
|
Note 🤖 Opus 5.5 replying on behalf of Victor. @maria-rcks Since your verification at |
|
Note 🤖 Opus 5.5 replying on behalf of Victor. I merged main |
|
Thanks for this. Main has the change since #36168. Main now drops only unreadable desktop-settings.json fields while preserving valid settings, including Local environment off, across saves. I compared your complete implementation and regression-test diff with the merge: both apply Schema.catchDecoding per field and retain the existing normalization, defaults, lenient JSON parsing, and write behavior. Closing as superseded. |




Problem
If
desktop-settings.jsonholds one value this build can't read (for example"updateChannel": "beta"from a hand edit or another build), the desktop app ignores the whole file and starts from defaults. The next settings save writes those defaults over the file, so the user's local environment, network access, Tailscale, WSL and window settings are gone for good.Change
The strict document decode in
readSettingsfailed before the field-by-fieldnormalizeDesktopSettingsDocumentcould run. It now drops a key whose value it can't read, by mapping the existing document schema's fields throughSchema.catchDecoding, so that field falls back to its default and every other field still loads. Malformed JSON, or a file that isn't an object, still falls back to defaults as before.Scope
A bug fix for lost data. It is a small, focused fix for an obvious bug, so it needs no issue: one bad field should not throw away the other valid settings. Possibly related: #26144 (
localEnvironmentEnabled: falsedisappeared), but that report doesn't say what the file held, so this PR doesn't claim to fix it.Verification
To see it on Linux (desktop app):
{ "localEnvironmentEnabled": false, "updateChannel": "beta" }todesktop-settings.json.localEnvironmentEnabled; with this PR it stays off and is kept.Linux desktop app built with
vp run build:desktopfrom main65c0195b46, then from this branch atd388a0a3d2(this PR merged with that main): unpackaged Electron 44 under Xvfb, an isolated home, environment named "Test machine", the same file written before each launch. Settings opened by URL over the debugging port; the app closed with Alt+F4 through the window manager (X input). The extendedDesktopAppSettings.test.tsload case fails with main'sDesktopAppSettings.tsand passes here (13/13).Main 65c0195: Local environment is on after loading the file
This PR at d388a0a: Local environment stays off
The saved file after the close, main
65c0195b46:This PR at
d388a0a3d2:Not checked:
The change in full and the tests
normalizeDesktopSettingsDocumentalready falls back field by field. The strict document decode inreadSettingsfails first, though, andEffect.orElseSucceedswaps in the defaults for every field. The document decode now drops a key whose value it can't read (for example"updateChannel": "beta"or"wslOnly": "yes"), so that field falls back to its default and every other field still loads. Field types, defaults, the normalizer and the write path are unchanged. Mapping the fields, instead of rewriting each one, also covers any field added later. A value the build can't read is still not kept: the next save rewrites the file from the loaded settings, the same as for values the normalizer already replaces, such as an out-of-range Tailscale port.vp test run src/settings/DesktopAppSettings.test.tsinapps/desktop: the existing lenient-JSON load case carries"updateChannel": "beta","wslOnly": "yes"and"localEnvironmentEnabled": false, then saves a setting and reloads. With main'sDesktopAppSettings.ts(from65c0195b46) it fails, because every field comes back as its default (localEnvironmentEnabled: true,serverExposureMode: "local-only",tailscaleServePort: 443,mainWindowBounds: null); with the fix, 13/13 pass andlocalEnvironmentEnabledstaysfalseafter the save and reload.d388a0a3d2, Node 26.12.1:vp run typecheckinapps/desktoppasses;vp run check:changedpasses (format, lint, both knip passes, typecheck, tests).DesktopAppSettings.tsthree times since this PR's base (chore(deps): upgrade Effect to 4.1.2 and alchemy to beta.85 #26833, fix(desktop): failed settings saves no longer leave temp files behind #29635, fix(desktop): let the window shrink to 400x360 so it fits half-screen tiles #28223);readSettingsstill ends inEffect.orElseSucceed(() => defaultSettings), and the merge was clean.In the desktop runs above, main's saved file held only
mainWindowBoundsafter the close; with this PR it kept"localEnvironmentEnabled": false, andupdateChannelwas dropped.Possibly related: #26144, where
localEnvironmentEnabled: falsedisappeared fromdesktop-settings.json. The run above shows the same symptom from a file with one unreadable value, but that report doesn't say what the file held, so this PR doesn't claim to fix it.Prior PRs
None make this fix. #3265, #3379 and #3432 by juliusmarminge reworked how desktop settings errors are structured and diagnosed. #26757 by t3dotgg adds a field to the same document schema and benefits from this without changes.
Generated with Claude Opus 5.5 and GPT-6.1 Terra and GPT-6.1 Sol in T3 Code Nightly