Repository navigation
[Bug]: V2 desktop seeds t3code-v2 Local State from a stale "T3 Code (Alpha)" profile, making connection-catalog.json undecryptable #15001
Description
Area: apps/desktop
Impact: Blocks work completely
Steps to reproduce
Windows machine that has used T3 Code since the Alpha era, so both of these exist:
%APPDATA%\T3 Code (Alpha)\Local State(stale, last written months ago)%APPDATA%\t3code\Local State(the profile stable builds actually read the safeStorage key from)
- On stable 0.0.45, have at least one saved remote connection so
~/.t3/userdata/connection-catalog.jsonexists. Everything works. - Install nightly 0.0.46-nightly.20261003.2610 (first Orchestrator V2 build) and launch it.
- The app relaunches with
--user-data-dir=%APPDATA%\t3code-v2.resolveUserDataPathcreates that folder and copiesLocal Stateinto it fromT3 Code (Alpha)because that folder exists, instead of fromt3code. - Open the app.
Expected behavior
The V2 profile is seeded with the key that actually encrypted the existing connection catalog (the t3code profile key on this machine), so saved connections load and the local environment registers.
Actual behavior
Every launch fails to decrypt connection-catalog.json. The web client reports "Could not load the local connection catalog", no environment gets registered (the renderer logs " is not connected" for the local machine itself), the sidebar shows no threads, nothing can be sent, and Settings shows "Connect an environment to choose its text generation model."
Switching back to stable 0.0.45 restores everything, because stable reads the key from %APPDATA%\t3code. Switching to the nightly breaks it again.
Evidence
I decrypted the catalog manually with each profile's os_crypt.encrypted_key (DPAPI unwrap, then AES-256-GCM on the v10 blob):
| Profile | Result |
|---|---|
T3 Code (Alpha) |
fails, GCM auth tag mismatch |
t3code |
decrypts (schemaVersion, targets, profiles, credentials, remoteDpopTokens) |
t3code-v2 (seeded by the nightly) |
fails, identical key to Alpha |
Relevant code in the shipped bundle (apps/desktop/dist-electron/main.cjs, resolveUserDataPath):
const legacyState = path.join(legacyPath, "Local State"); // T3 Code (Alpha)
const sourceState = (yield* inspect(legacyState))
? legacyState
: path.join(input.appDataDirectory, "t3code", "Local State");The Alpha profile takes precedence whenever it exists, regardless of which key the catalog was encrypted with. Note that the nightly also re-encrypts clerk-tokens.json with the new (wrong) key, so simply swapping the key afterwards invalidates that token.
Logs
desktop.trace.ndjson (repeated on every launch, 24 times tonight):
DesktopConnectionCatalogStoreProtectionError: Desktop connection catalog protection failed during decrypt-catalog at C:\Users\<user>\.t3\userdata\connection-catalog.json.
at ...\resources\app.asar\apps\desktop\dist-electron\main.cjs:107992:201
[cause]: ElectronSafeStorageDecryptError: Electron safe storage failed to decrypt a string.
[cause]: Error: Error while decrypting the ciphertext provided to safeStorage.decryptString.
Renderer (otlp spans in server.trace.ndjson):
web.connectionStorage.loadCatalog ConnectionTransientError: Could not load the local connection catalog: Error: Error invoking remote method 'desktop:get-connection-catalog': DesktopConnectionCatalogStoreProtectionError: ...
EnvironmentRpc.request EnvironmentRpcUnavailableError: <hostname> is not connected. (environment.id = the local primary environment)
Stable-era logs from earlier the same day contain zero decrypt-catalog failures.
Version / environment
- T3 Code 0.0.46-nightly.20261003.2610 (nightly track), broken; 0.0.45 stable works
- Windows 11 Pro 10.0.26200, x64
- Claude Code 2.1.288, Codex 0.160.0 (both above the V2 minimums in [IMPORTANT] Moving from T3 Code Orchestrator V1 to V2 #14871)
- The V2 migration itself succeeded: statev2.sqlite has all 169 threads imported with no
last_error
Suggested fix
When seeding t3code-v2\Local State on win32, try each candidate source (t3code, then T3 Code (Alpha)) and pick the one whose key actually decrypts the existing connection-catalog.json; or prefer t3code over the Alpha folder, since the Alpha folder is stale on long-time Windows installs. Independently, a decrypt failure should degrade to an empty catalog rather than leaving the local environment unregistered (see #8341 and the closed #13656).
Workaround
Close the nightly, copy os_crypt.encrypted_key from %APPDATA%\t3code\Local State into %APPDATA%\t3code-v2\Local State, relaunch, sign in again. Deleting connection-catalog.json also works but loses saved connections.
Related
- [Bug]: Orphaned safeStorage key makes connection-catalog.json permanently undecryptable, blocking all target listing on Windows #8341 (orphaned safeStorage key, open) — the two comments from 2026-10-03 describe this same V2 scenario
- fix(desktop): recover undecryptable connection catalogs safely #13656 (closed, unmerged) — recovery path for undecryptable catalogs
- [IMPORTANT] Moving from T3 Code Orchestrator V1 to V2 #14871 — V1 to V2 migration guide
Activity
juliusmarminge commentedon Oct 3, 2026
Note
Grok responding on behalf of Julius.
Triage
Thanks for the thorough investigation, @J-clone. Decrypting the catalog with each profile's key made this easy to pin down. We confirmed it on
main(43bd667). This is a Windows-only bug in how V2 seeds its profile, and it's still present.What V2 does:
resolveUserDataPathputs the V2 app in%APPDATA%\t3code-v2. On win32 only, it copiesLocal Stateonce:t3code-v2\Local Statealready exists, it keeps it.T3 Code (Alpha)\Local Stateif that file exists.t3code\Local State.t3code/apps/desktop/src/app/DesktopUserData.ts
Lines 43 to 66 in 43bd667
That order matches what you found. On your machine, and in the 2026-10-03 notes on #8341,
connection-catalog.jsondecrypts with thet3codekey, and the Alpha key is stale. V2 still prefers Alpha whenever itsLocal Stateexists, so the new profile gets a key that can't open the catalog.DesktopUserData.test.tstests each source on its own but never the case where both files exist. macOS and Linux don't copyLocal Stateat all.Why everything stops working: after the bad seed, the outage comes from the existing hard failure tracked in #8341. A
safeStorage.decryptStringfailure becomesDesktopConnectionCatalogStoreProtectionError, the catalog can't load, and the local environment never connects. #13656 would have recovered with an empty catalog, but it was closed without merging, so that recovery stays on #8341.Fix direction: preferring
t3codeover Alpha would fix the installs reported so far, but it would pick the wrong key on any Windows profile that really did encrypt with Alpha. The safer fix is that whenconnection-catalog.jsonexists, V2 copies whicheverLocal Statekey can actually decrypt it. The open PR #14265 also changes how the Windows encryption profile is chosen, so it's worth checking alongside this.Already-affected installs: a fix won't repair profiles that
0.0.46-nightly.20261003.2610already created, because V2 never re-seeds oncet3code-v2\Local Stateexists. Those installs still need your workaround: copyos_crypt.encrypted_keyover from thet3codeprofile before anything else is written with safe storage, or set the undecryptable catalog aside. Signing in again afterwards is expected, since onlyLocal Stateis copied. Anything the nightly already re-encrypted insidet3code-v2won't decrypt after the key is swapped.We're keeping this open as a bug, separate from #8341.
darkyeg commentedon Oct 3, 2026
Confirmed the same failure on Windows with 0.0.46-nightly.20261003.2623, commit fed41fa. This also affects the later nightly, not only
.2610.Read-only checks before recovery:
%APPDATA%\t3code\Local State.%APPDATA%\T3 Code (Alpha)\Local Stateand%APPDATA%\t3code-v2\Local State.t3code's key.state.sqliteandstatev2.sqliteeach contained the same 8 non-deleted projects and 42 non-deleted threads. The V2 thread projection also contained 42 threads.DesktopConnectionCatalogStoreProtectionErrorduringdecrypt-catalog, caused byElectronSafeStorageDecryptError.Recovery verified on this machine:
v10payload with the oldt3codekey in memory.t3code-v2key and a fresh GCM nonce; verified an exact plaintext round-trip before and after writing.This preserves the V2 key for credentials/cookies that may already have been written with it, and retains saved remote connection credentials rather than deleting the catalog. After restart,
desktop.connectionCatalogStore.getand its IPC call both returnedSuccess; environment handshake and project metadata snapshot calls also succeeded. The user confirmed chats appeared again. The saved laptop connection was retained and its environment descriptor returned HTTP 200.For a regression test, please cover both legacy profiles coexisting with different keys, with the catalog encrypted using the
t3codekey. Also cover recovery after an already-created V2 profile has started encrypting other credentials with the Alpha-derived key; reseeding only on first launch will not repair those users.No raw logs, tokens, encryption keys, hostnames, workspace paths, or conversation content are attached.
Timmyy3000 commentedon Oct 3, 2026
Hit this too on Windows 11 after updating to the Nightly channel today (2026-10-03). Desktop trace showed
DesktopConnectionCatalogStoreProtectionError … during decrypt-catalog, and the UI showed "local environment is having problem setting up" with no projects or threads. The data was intact instatev2.sqlite(the v2 migration succeeded). Workaround: quit the app, rename~/.t3/userdata/connection-catalog.jsonto.bak, relaunch.kharitonov-egor commentedon Oct 4, 2026
I'm hitting this too, on Windows 11 Pro (10.0.26200).
What happened. I updated from stable to nightly
0.0.46-nightly.20261004.2644. The sidebar showed "No projects yet". Rolling back to0.0.46-nightly.20261003.2632didn't help, because that build is V2 as well. Going back to0.0.45-nightly.20261002.2595, the last nightly before #2829, brought every project and thread back.The data was fine.
~/.t3/userdata/statev2.sqlitehad a complete migration: 27 rows inprojection_projects, 422 inorchestration_v2_projection_threads, 422 inorchestration_v2_legacy_imports. Nothing was lost. The app just couldn't register the local environment.Matches this issue. I have all of these under
%APPDATA%:T3 Code (Alpha),t3code,t3code-dev,t3code-v2. The desktop trace has 48DesktopConnectionCatalogStoreProtectionErrorentries acrossdesktop.trace.ndjsonanddesktop.trace.ndjson.1, all from V2 launches.Confirmed on 2644, so the bug is still present in the Oct 4 nightly as well as 2610 and 2623. For now I'm staying on 2595 until this is fixed.
Sebastian-Neubert commentedon Oct 7, 2026
Independent confirmation on Windows after upgrading from stable
0.0.45to0.0.46-nightly.20261007.2787. This is still reproducible in the October 7 nightly, which was the newest published nightly when checked.Read-only diagnosis before recovery:
%APPDATA%\t3code\Local State.DesktopConnectionCatalogStoreProtectionErrorduringdecrypt-catalog, caused byElectronSafeStorageDecryptError.Recovery was verified in the installed desktop app, without resetting the catalog or recreating either database:
os_crypt.encrypted_keyin V2'sLocal Stateto the validated working stable-profile value.T3 Connect required a fresh sign-in after the key change, which the user completed successfully. This supports the existing warning about credentials written under the initial V2 key.
The source-selection order and early return for an existing V2
Local Stateare still present in current main at26285ab8. #15072 is already in this nightly, but its Local Storage import does not repair this encryption-key mismatch.Useful regression cases would include both legacy profiles coexisting with different keys, a catalog encrypted under either candidate key, and an already-created V2 profile containing credentials encrypted under its initial key. Recovery should retain saved connections and account for V1/V2 sharing the catalog, rather than automatically replacing recoverable data with an empty catalog. Re-encrypting that shared catalog under a different V2 key also needs a V1 compatibility check.
Investigated with Codex. No keys, tokens, raw logs, conversation content, or identifying paths are included here.
CountMyBands commentedon Oct 10, 2026
Still reproducible on
0.0.46-nightly.20261010.2935(Windows 11 Pro 10.0.26200, x64), after upgrading from stable through the desktop app.%APPDATA%containsT3 Code (Alpha),t3code,t3code-dev, andt3code-v2.desktop.trace.ndjsonlogsDesktopConnectionCatalogStoreProtectionError … during decrypt-catalogon every nightly launch (28 entries in the current file).statev2.sqlitewas seeded fromstate.sqliteat first launch. Both have 2,114 threads and 36 projects.orchestration_v2_projection_threadsandorchestration_v2_legacy_importseach have 2,114 rows, with 0 pending transcripts and 0 import errors.~/.t3/userdata/connection-catalog.jsonto.bak, relaunch. All threads came back.state.sqlitekept being written by the stable build for ~30 minutes after V2 seededstatev2.sqlite, and the seed never runs again, so that work isn't in V2. Probably worth a separate note if the cutover is meant to be one-way.Diagnosed via
t3 triagewith Claude Code (Claude Opus 5.5).Stebulous commentedon Oct 15, 2026
Note
Claude (Opus 5.5) posting on behalf of @Stebulous.
Hit on
0.0.46-nightly.20261014.3132(Windows 11 Pro 10.0.26200, x64).apps/desktop/src/app/DesktopUserData.tsis byte-identical from339179f(nightly 3145) through nightly 3176,v0.1.0andmainatd2d59fa, so the bug is still present. Now that 0.1.0 is on stable, any Windows install that still hasT3 Code (Alpha)\Local Stateand not3code-v2profile yet takes this path on upgrade.0.0.45by switching the update track to Nightly.%APPDATA%had bothT3 Code (Alpha)(last written March) andt3code(the profile in use since June).t3code-v2\Local Statehad the sameos_crypt.encrypted_keyasT3 Code (Alpha), nott3code.desktop.trace.ndjsonloggedDesktopConnectionCatalogStoreProtectionError … during decrypt-catalogon each launch.statev2.sqlitehad 354 rows in bothorchestration_v2_legacy_importsandorchestration_v2_projection_threads, with 0 import errors.Workaround that keeps saved connections: with the app fully quit, copy only
os_crypt.encrypted_keyfrom%APPDATA%\t3code\Local Stateinto%APPDATA%\t3code-v2\Local State(back up the file first), then relaunch. The catalog decrypted, the local environment connected, and saved remote environments came back. Unlike renamingconnection-catalog.json, this keeps them.clerk-tokens.jsonwas rewritten on the next launch with no decrypt failures in the desktop trace.Edited 2026-10-16: corrected the build list; 3132 was not the newest nightly.
g1331 commentedon Oct 16, 2026
Independent confirmation on stable 0.1.0: existing V2 profile cannot decrypt the shared connection catalog
Adding an incident observed after a Windows desktop update to stable 0.1.0 on 2026-10-16. This appears to be the already-affected-profile case discussed above, so I am adding evidence here rather than opening a duplicate.
Area, environment, and impact
%APPDATA%\t3codeand%APPDATA%\t3code-v2already exist. V2 profile artifacts predate this update.Incident sequence and expected behavior
~/.t3/userdata/connection-catalog.jsonand an already-created V2 profile.Expected: the local environment and saved remote entries should load, and existing projects and provider settings should be available.
This is captured field evidence, not a clean-install reproduction of how the mismatched keys were first created.
Read-only findings before any recovery
Authenticated decryption of the same existing catalog was tested in memory using each profile's Windows-protected key: DPAPI unwrap, then AES-GCM authentication of the existing
v10payload.%APPDATA%\t3code\Local State%APPDATA%\t3code-v2\Local StateAdditional observations:
os_crypt.encrypted_keyvalues. Neither value is included here.%APPDATA%\T3 Code (Alpha)\Local Stateis absent at the time of inspection. I cannot establish whether an Alpha profile ever existed or why the V2 key originally diverged; this report does not claim to reproduce the original Alpha-selection trigger.settings.jsonretains enabled Codex and Claude provider instances.Minimal redacted diagnostic excerpt
The same failure propagates through the connection-catalog IPC read.
Scope and recovery status
The immediate local fault is verified: the shared catalog authenticates with the stable-profile key and fails with the current V2-profile key. The data files and provider settings remain present.
The v0.1.0 source still returns the existing V2 profile immediately when its
Local Stateexists, so first-launch seeding alone cannot repair this already-created profile:DesktopUserData.ts at v0.1.0.
No recovery has been applied in this incident yet. In particular, neither profile key, the catalog, nor either database has been replaced or deleted. No successful UI recovery is claimed.
A separate saved remote server is still on V1. Its protocol compatibility after reconnect is a separate issue; it does not explain why the local catalog fails authenticated decryption or why the local environment cannot load.
Redaction
No usernames, hostnames, IP addresses, project/repository names or workspace paths, process IDs, environment/thread/tunnel identifiers, account details, pairing codes, tokens, encryption keys, ciphertext, conversation content, screenshots, databases, or raw logs are included. Only the minimal normalized error excerpt and non-identifying diagnostic results are provided.
Investigation and report preparation used Codex on the affected user's behalf.
ikifar2012 commentedon Oct 16, 2026
Confirmed a related encryption-key mismatch after updating the stable Windows desktop app to 0.1.0, without using nightly builds.
What happened and reproduction
This is field evidence; the original cause of the key divergence has not been reproduced in isolation.
Diagnosis and evidence
npx t3 triage).%APPDATA%\t3code\Local Stateand%APPDATA%\t3code-v2\Local Statecontained different encryption keys. The V2 file was created at the update.%APPDATA%\T3 Code (Alpha)\Local Statewas absent at inspection, so this does not establish the stale-Alpha selection trigger described in this issue.Redacted error chain:
Recovery verification
With the app fully closed, backed up the V2
Local Statefile and replaced onlyos_crypt.encrypted_keywith the verified old stable profile key. Authenticated catalog decryption then succeeded with the V2 profile. After relaunch, desktop and renderer catalog reads succeeded, local and WSL backends reached readiness, and environment RPC and initial synchronization succeeded. Visual confirmation of restored threads and T3 Connect sign-in is still pending.The exact migration mechanism remains unresolved. Related: #8341. The v0.1.0 source retains an existing V2
Local Statewithout checking whether its key can decrypt the shared catalog: DesktopUserData.ts.Prepared with GPT-6 in Codex via
t3 triageon the affected user's behalf.Maxborland commentedon Oct 16, 2026
Confirmed on the stable 0.1.0 release (Windows 11, updated from the previous stable through the updater), so this now reaches stable users, not only nightly.
Same picture as the report:
t3code-v2\Local Statewas seeded with the staleT3 Code (Alpha)key,connection-catalog.jsononly decrypts with thet3codeprofile key, and the app looks like a fresh install ("No projects yet", Settings → Providers shows "Connect an environment to set up its providers."). The server side was fine:statev2.sqlitehad every legacy thread imported (orchestration_v2_legacy_importsrows with nolast_error), so no data was lost.Two details that may help:
targets,profiles,credentials,remoteDpopTokens,disabledEnvironmentIdsall had 0 entries). So you don't need saved remote connections to hit this: an existing but undecryptable catalog blocks the local environment by itself ([Bug]: Orphaned safeStorage key makes connection-catalog.json permanently undecryptable, blocking all target listing on Windows #8341).t3codekey intot3code-v2\Local State(which invalidatesclerk-tokens.jsonand anything else V2 already encrypted), re-encrypt the catalog. Decrypt it with whichever old profile key works, encrypt it again with thet3code-v2key, and write it back. After a restart, everything loaded and sign-in still worked.PowerShell 7 script (dry run by default,
-Applywrites, keeps a backup, prints no secrets)realS3BI commentedon Oct 16, 2026
Confirmed on stable 0.1.0 (Windows), after updating through the desktop app. Same symptoms as above: "No projects yet", no environment, no providers.
The key-copy workaround fixed it for me. Fully quit T3 Code (including the tray icon), then in PowerShell:
After relaunching, projects, threads and saved connections were back. I had to sign in to T3 Connect again, as others here mentioned.
To revert:
Copy-Item "$env:APPDATA\t3code-v2\Local State.bak" "$env:APPDATA\t3code-v2\Local State" -Forcejohn3374 commentedon Oct 16, 2026
Another instance on stable 0.1.0, Windows 11 Pro 10.0.26200, reached through the normal in-app auto-update from 0.0.45 (not nightly). Every launch logged
DesktopConnectionCatalogStoreProtectionError ... decrypt-catalog, the web client reported "Could not load the local connection catalog", and the sidebar was empty. Rolling back to 0.0.45 restored everything.Key test (DPAPI unwrap of each profile's
os_crypt.encrypted_key, then AES-256-GCM on thev10blob):t3codeT3 Code (Alpha)t3code-v2t3code-v2\Local Statehad been seeded from the Alpha profile on 2026-10-03 by a V2 nightly, matching the triage above.Recovery that preserved the saved connections and the sign-in: with the app quit, decrypt the catalog with the
t3codekey and re-encrypt the identical plaintext with thet3code-v2key (fresh nonce), keeping a backup. After relaunchdesktop.connectionCatalogStore.getsucceeded and both relay connections were restored. Note the web client briefly dropped the relay environments at startup viaEnvironmentRegistry.removeRelayEnvironmentsbefore the Clerk session finished loading, then re-registered them about a minute later.Same machine also hit #15017 (stale
statev2.sqlitesnapshot) because of the rollback.Filed by Claude Fable 5.1 via
t3 triage.claudioscatoli commentedon Oct 22, 2026
Confirmed on stable 0.1.1 and 0.1.2-nightly.20261022.3512 (Windows 11 Pro 10.0.26100, x64, desktop app with its local server). So this bug now reaches stable users who update from 0.0.x.
Read-only diagnosis:
%APPDATA%containsT3 Code (Alpha),t3codeandt3code-v2.t3code-v2\Local Statewas seeded on 2026-10-16, and itsos_crypt.encrypted_keyis identical to Alpha's, not tot3code's.connection-catalog.json(v10, last written 2026-10-20 by a pre-0.1.0 build) decrypts with thet3codekey. It fails with both the Alpha key and thet3code-v2key.connectionCatalogStore.getsuccess was on 2026-10-20 (pre-0.1.0 build). Every get from the first 0.1.1 launch on 2026-10-22 fails withDesktopConnectionCatalogStoreProtectionError(decrypt-catalog) →ElectronSafeStorageDecryptError.t3CLI + web app show all projects and threads.DesktopUserData.tshas not changed onmainsince 2026-10-16, so this is still unfixed.Given #23470, an affected install can also lose the undecryptable catalog to an empty overwrite. That makes this more urgent now that stable users are hitting it.
Workaround: copy
os_crypt.encrypted_keyfromt3code\Local Stateintot3code-v2\Local Statewith the app closed, after backing up both files.Verified: after the swap, 0.1.1 reads the original catalog (
connectionCatalogStore.get→ Success) and all environments are back.Diagnosed with
t3 triageby Claude Opus 5.5 (claude-opus-5-5) in Claude Code.