Hit this on 0.0.33, four weeks after you filed it. Windows 11, WSL2 Ubuntu, same three symptoms: no providers, no projects, no sessions.
Some numbers that might help, plus a confirmation that the recovery in #5902 works.
The file
Mine was 860 bytes of NUL. Yours was 1408. After recovery the app wrote a fresh one at 860 bytes, so the size follows the catalog contents, and in both cases the size reached disk and the data didn't.
The envelope:
| 1 | {"version":1,"encryptedCatalog":"<base64>"} |
So the outer document is what fails to decode, matching the description in #5902. Every other JSON file in .t3\userdata parsed fine.
On the ~3s cadence
I sampled the mtime with the app idle, nothing running:
| 1 | 16:34:14 16:34:21 16:34:29 16:34:36 16:34:45 |
| 2 | 16:34:53 16:35:01 16:35:10 16:35:19 16:35:26 |
It rewrites every 6 to 9 seconds, the same 860 bytes, and it doesn't stop. No state change behind any of it.
The part that surprised me: my corrupt file carried an mtime of 15:37, but I rebooted at 16:05. At that cadence the app wrote it another 240 times in between, and Windows flushed none of them, data or metadata. So the exposure isn't a few seconds around one write. I lost 28 minutes of writes to this path, which makes the odds of landing on it worse than the title suggests.
Nothing else broke
You're right that the data survives:
- Windows
state.sqlite, 59 MB:pragma quick_checkreturnsok - WSL
state.sqlite, 344 MB: same
For anyone stuck here before #5902 lands:
- Quit T3 Code
mv ~/.t3/userdata/connection-catalog.json ~/.t3/userdata/connection-catalog.json.bak- Start it again
I had a valid catalog back within seconds, my projects and threads where I left them, and both environments reconnected on their own. From desktop.trace.ndjson:
| 1 | catalogStore.get Failure last at 16:09:53 |
| 2 | catalogStore.get Success last at 16:26:26 |
I never re-added the WSL connection. desktop-settings.json still held wslBackendEnabled: true and wslDistro: "Ubuntu", so the app picked it up again.
That's the same place #5902 gets to on its own by quarantining the document and treating the catalog as missing, so the Option.none path gives you everything back instead of a half-working app. The draft looks like it's sitting on the Effect.catchTag to Effect.catchTags convention check.
The logs point the wrong way
Worth a warning for whoever debugs this next. My child log was full of:
| 1 | Timed out after 60000ms waiting for desktop backend readiness at http://<wsl-ip>:3774/.well-known/t3/environment. |
WSL hadn't finished booting inside the 60 second probe, and I chased that first. Meanwhile the UI sat empty and both backends answered:
| 1 | GET http://127.0.0.1:3773/.well-known/t3/environment -> 200 |
| 2 | GET http://<wsl-ip>:3774/.well-known/t3/environment -> 200 |
The catalog gate runs ahead of connection health, so a healthy backend still leaves you with an empty app.
One more thing I noticed while testing: the probe doesn't retry after it gives up. An environment that comes up after those 60 seconds stays unavailable until you restart the app, valid catalog or not.