You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Settings saves revert external edits to settings.json #18571
I searched existing issues and did not find a duplicate.
I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
Run t3 serve and connect a client.
Make the client save settings faster than every 100 ms, or save once within 100 ms after the next step.
Replace settings.json from outside T3 Code, for example with a script that adds a customModels entry and renames the new file into place.
Read settings.json again.
Expected behavior
The save applies its patch to the file on disk. The external edit stays.
Actual behavior
The save writes the server's cached settings back, and the external edit is gone.
Cause:
updateAndPersistSettings (apps/server/src/serverSettings.ts) applies the patch to the cached settings and writes the whole result.
The cache refreshes only through the file watcher, debounced to 100 ms of quiet (Stream.debounce).
Every save also triggers a watcher event. Saves that arrive less than 100 ms apart keep the debounce from firing, so the cache never reloads and every save writes the old file back.
We hit this with saves 20 to 40 ms apart from the client loop in #18572. A fleet script's edit to settings.json was reverted about 20 seconds after it landed.
A related case: once the watcher has loaded a settings.json that does not parse, the cache holds defaults. The next save then writes defaults plus the patch over the user's file, although the loader says such a file "must stay on disk for the user to repair".
Impact
Major degradation or frequent failure
Version or commit
0.0.46-nightly.20261010.2935 (98beed1). Same code on origin/main f498b35.
Environment
t3 serve on macOS and Linux.
Workaround
After an external edit, wait until settings.json has stopped changing, then read it back and apply the edit again if it was reverted.
Confirmed on main. This is a bug, not intended behavior. The server watches settings.json so that external edits are picked up, and the loader says outright that a file it can't parse "must stay on disk for the user to repair". Saves currently break both of those.
What main does (apps/server/src/serverSettings.ts):
updateAndPersistSettings applies the patch to the cached settings (getSettingsFromCache) and writes the whole result back with writeSettingsAtomically. It never re-reads the file.
The cache is only invalidated by the watcher, which goes through Stream.debounce(100ms). Each save fires another watcher event, so saves less than 100 ms apart keep resetting the debounce. The cache never reloads, and every save writes the stale snapshot over the external edit.
If the file doesn't parse, the cache holds defaults (settingsFileTrusted = false). The next save then writes defaults plus the patch over the user's broken file, which contradicts that loader comment.
The trigger you hit, saves 20 to 40 ms apart, comes from #18572. That one is tracked separately, but any burst of saves can cause this. Until it's fixed, the workaround is to make external edits while no client is saving, then read the file back to check.
Activity
juliusmarminge commentedon Oct 12, 2026
Note
Grok responding on behalf of Julius.
Confirmed on main. This is a bug, not intended behavior. The server watches
settings.jsonso that external edits are picked up, and the loader says outright that a file it can't parse "must stay on disk for the user to repair". Saves currently break both of those.What main does (
apps/server/src/serverSettings.ts):updateAndPersistSettingsapplies the patch to the cached settings (getSettingsFromCache) and writes the whole result back withwriteSettingsAtomically. It never re-reads the file.Stream.debounce(100ms). Each save fires another watcher event, so saves less than 100 ms apart keep resetting the debounce. The cache never reloads, and every save writes the stale snapshot over the external edit.settingsFileTrusted = false). The next save then writes defaults plus the patch over the user's broken file, which contradicts that loader comment.The trigger you hit, saves 20 to 40 ms apart, comes from #18572. That one is tracked separately, but any burst of saves can cause this. Until it's fixed, the workaround is to make external edits while no client is saving, then read the file back to check.