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]: Mac Nightly: projects and chats appear missing after this morning's update #22216
I searched existing issues and did not find a duplicate of this Nightly update failure. Related issues are listed below.
I included enough detail to reproduce or investigate the problem.
Area
apps/desktop
Steps to reproduce
Observed on an existing Mac desktop installation; a clean-profile reproduction has not been established:
Have existing projects and chat history in T3 Code.
Update the Mac desktop app this morning, 20 October 2026.
Reopen the app.
Expected behavior
Existing projects and chats remain accessible after an update.
Actual behavior
All my projects and chats appeared to be missing after the update, making it look as though I had lost all my data.
Investigation identified a connection-catalog decryption failure. The history was still present in the database; the app could not load access to it.
This is a Nightly report. #20906 describes a related encryption-identity problem, but explicitly excludes Nightly and is now closed as fixed. Please check whether this is a follow-up regression from that fix, rather than assuming its original channel scope still holds.
Impact
Blocks work completely
Version or commit
T3 Code Nightly. The exact build is omitted from this public report.
Environment
Mac desktop app.
Logs or stack traces
Generic error, without local paths or full logs:
DesktopConnectionCatalogStoreProtectionError:
Desktop connection catalog protection failed during decrypt-catalog.
Caused by:
ElectronSafeStorageDecryptError:
Electron safe storage failed to decrypt a string.
The exact encryption-key mismatch has not been established.
Screenshots, recordings, or supporting files
No private files or full logs attached.
Workaround
Access was restored locally after preserving the failing catalog and resetting the catalog state. This is a workaround, not a confirmed fix for the underlying decryption failure.
Related: #20906 and #20907 (encryption-identity change), #8341 and #15001 (similar Windows failures).
On the first launch of the new build, Electron created a new Keychain item, T3 Code (Nightly) Safe Storage, at 08:12:24Z. The first decrypt-catalog failure is in the same second.
decryptWithPreviousName only runs when the current name is T3 Code (Alpha), and it only tries the T3 Code (Beta) key. Nightly has no fallback, so the old t3code key is never tried.
[Bug]: Saved connections no longer decrypt on Linux and macOS after the Alpha → Beta rename #20906 assumed Nightly was safe because it "has always been packaged as T3 Code (Nightly)". On this Mac, no T3 Code (Nightly) Safe Storage item existed before today. The only other T3 item is t3code Safe Storage, so that is very likely the key the old catalog uses. I have not yet confirmed this by decrypting with it.
Suggested fix
On macOS/Linux nightly, when the catalog fails to decrypt, also try the t3code Safe Storage / t3code Key key, then re-encrypt with the new key, the same way the Beta fallback works.
Version
Last good: 0.1.1-nightly.20261020.3386. First bad: 0.1.1-nightly.20261020.3399.
Environment
macOS (Darwin 27.0.0), Apple Silicon, desktop app with its local server.
Evidence
Keychain (names and creation times only):
t3code Safe Storage / t3code Key created 2026-06-25
T3 Code (Nightly) Safe Storage / T3 Code (Nightly) Key created 2026-10-20T08:12:24Z
desktop.trace.ndjson: first decrypt-catalog failure at 2026-10-20T08:12:24Z, none in older rotated logs.
connection-catalog.json was last written at 07:40Z by build 3386. Its ciphertext starts with "v10".
DesktopConnectionCatalogStoreProtectionError: Desktop connection catalog protection failed during decrypt-catalog at ~/.t3/userdata/connection-catalog.json.
at desktop.connectionCatalogStore.recoverPreviousIdentityCatalog
[cause]: ElectronSafeStorageDecryptError: Electron safe storage failed to decrypt a string.
[cause]: Error: Error while decrypting the ciphertext provided to safeStorage.decryptString.
Workaround
Not run yet: quit the app, decrypt the catalog with the t3code Safe Storage key, and re-encrypt it with the T3 Code (Nightly) Safe Storage key. I'll report back if it works.
Filed by: Claude Code (claude-opus-5-5), following the t3 triage playbook.
Update:#20907 was reverted in #22219. The next Nightly build goes back to the old t3code key.
If you have not run the script yet, do not run it. Wait for the next Nightly build.
Do not run this script after you update to that build. It would break your saved connections again.
If you ran the script and then updated: quit T3 Code (Nightly) and sign in to T3 Connect again first if needed. Then copy the backup the script made (connection-catalog.json.bak-<number> in ~/.t3/userdata) back over connection-catalog.json. That backup uses the old key.
Everyone who launched build .3399 must sign in to T3 Connect again: the Clerk session (clerk-tokens.json) uses the same key and is lost.
Confirmed on a second Mac (desktop, Nightly 0.1.1-nightly.20261020.3399, macOS arm64). This is a regression from #20907. The data is not lost: the local server and database are fine. Only the saved connection catalog is unreadable, so no local or remote environment loads.
DesktopSafeStorageIdentity.decryptWithPreviousName runs only when the name is T3 Code (Alpha), and it only tries the Beta key. So Nightly has no recovery path.
Checked: the existing connection-catalog.json decrypts with the t3code key to a valid catalog, and fails with the T3 Code (Nightly) key.
Workaround (macOS)
This script decrypts the catalog with the old key and encrypts it again with the new Nightly key. It makes a backup first and changes nothing unless an old key works. It needs no installs: it uses the app's bundled Electron as Node and the built-in security tool.
Quit T3 Code (Nightly) with Cmd+Q.
Save the script below as fix-t3-nightly.sh. Do not paste it directly into your shell.
Run bash fix-t3-nightly.sh.
Click Allow on each Keychain prompt.
Open T3 Code (Nightly) again.
fix-t3-nightly.sh
#!/bin/bash# Restores saved connections (local projects + remotes) after the 2026-10-20# T3 Code Nightly update on macOS. See https://github.com/pingdotgg/t3code/issues/22216## The update moved the encryption key to a new Keychain item, so the app can no# longer read connection-catalog.json. This script decrypts the file with the# old key and encrypts it again with the new one. It makes a backup first.set -euo pipefail
BIN="/Applications/T3 Code (Nightly).app/Contents/MacOS/T3 Code (Nightly)"
CATALOG="${CATALOG:-$HOME/.t3/userdata/connection-catalog.json}"
NEW_NAME="T3 Code (Nightly)"
OLD_NAMES=("t3code""t3code-v2""Electron")
has_key() { security find-generic-password -s "$1 Safe Storage" -a "$1 Key">/dev/null 2>&1; }
read_key() { security find-generic-password -s "$1 Safe Storage" -a "$1 Key" -w; }
[ "$(uname)"= Darwin ] || { echo"This fix is for macOS only.";exit 1; }
[ -x"$BIN" ] || { echo"T3 Code (Nightly) is not in /Applications.";exit 1; }
[ -f"$CATALOG" ] || { echo"No saved connections file at $CATALOG. Nothing to fix.";exit 0; }
if pgrep -xq "T3 Code (Nightly)";thenecho"Quit T3 Code (Nightly) first (Cmd+Q), then run this again.";exit 1
fi
has_key "$NEW_NAME"|| { echo"Open T3 Code (Nightly) once, quit it, then run this again.";exit 1; }
# Chromium safeStorage on macOS: "v10" + AES-128-CBC, PBKDF2-SHA1("saltysalt", 1003), IV of spaces.# Exit codes: 0 = fixed, 2 = already readable, 3 = OLD_KEY is not the right key.
JS='const fs = require("fs"), crypto = require("crypto");const file = process.env.CATALOG;const doc = JSON.parse(fs.readFileSync(file, "utf8"));const blob = Buffer.from(doc.encryptedCatalog, "base64");const iv = Buffer.alloc(16, 0x20);const keyFor = (pw) => crypto.pbkdf2Sync(pw, "saltysalt", 1003, 16, "sha1");const decrypt = (pw) => { if (!pw || blob.subarray(0, 3).toString("latin1") !== "v10") return null; try { const d = crypto.createDecipheriv("aes-128-cbc", keyFor(pw), iv); const text = Buffer.concat([d.update(blob.subarray(3)), d.final()]).toString("utf8"); return typeof JSON.parse(text) === "object" ? text : null; } catch { return null; }};if (decrypt(process.env.NEW_KEY) !== null) process.exit(2);const text = decrypt(process.env.OLD_KEY);if (text === null) process.exit(3);const c = crypto.createCipheriv("aes-128-cbc", keyFor(process.env.NEW_KEY), iv);const out = Buffer.concat([Buffer.from("v10"), c.update(text, "utf8"), c.final()]);const backup = `${file}.bak-${Date.now()}`;fs.copyFileSync(file, backup);const tmp = `${file}.tmp-${process.pid}`;fs.writeFileSync(tmp, JSON.stringify({ version: 1, encryptedCatalog: out.toString("base64") }) + "\n", { mode: fs.statSync(file).mode });fs.renameSync(tmp, file);console.log(`Backup: ${backup}`);'run_node() {
CATALOG="$CATALOG" NEW_KEY="$NEW_KEY" OLD_KEY="$1" ELECTRON_RUN_AS_NODE=1 \
"$BIN" -e "$JS"2>>(grep -v "Node.js environment variables are disabled">&2)
}
echo"macOS will ask for Keychain access. Click Allow (not Always Allow)."
NEW_KEY="$(read_key "$NEW_NAME")"
rc=0; run_node ""|| rc=$?
[ "$rc"= 2 ] && { echo"Your saved connections are already readable. Nothing to fix.";exit 0; }
fornamein"${OLD_NAMES[@]}";do
has_key "$name"||continueecho"Trying the \"$name\" key..."
rc=0; run_node "$(read_key "$name")"|| rc=$?if [ "$rc"= 0 ];thenecho"Fixed. Open T3 Code (Nightly) again.";exit 0;fi
[ "$rc"= 3 ] || { echo"Unexpected error (code $rc). Your file was not changed.";exit 1; }
doneecho"No old key could read your saved connections. Your file was not changed."echo"Please comment on https://github.com/pingdotgg/t3code/issues/22216"exit 1
Linux is not covered by this script. A fix PR is in progress.
Diagnosed with t3 triage by Claude Opus 5.5 in Claude Code.
Reacted by kuba, Alex, David McBacon, Néstor and Yeray Lage
Confirmed the same regression on Linux x64 (Arch, kernel 7.2.11-arch1-1), using the desktop AppImage and its local server.
Reproduction: From an existing Nightly installation with projects and saved environments, I used the update button in the desktop app. The affected server reported 0.1.1-nightly.20261020.3399. After the update, the desktop showed no projects or other environments. Signing in to T3 Connect again did not restore them.
Local evidence (redacted):
desktop.trace.ndjson recorded DesktopConnectionCatalogStoreProtectionError during decrypt-catalog in desktop.connectionCatalogStore.get and desktop.connectionCatalogStore.recoverPreviousIdentityCatalog at approximately 08:28 and 08:31 UTC on 20 October. The catalog IPC read failed too.
The local server still answered /.well-known/t3/environment and reported build .3399 before rollback.
The current SQLite database retained 8 non-deleted projects and 9 non-deleted threads. No database repair was needed.
The .3399 source only tries previous-name recovery for T3 Code (Alpha) and the Beta key; it has no Nightly fallback. This is consistent with the encryption-identity regression diagnosed above. I did not inspect or test the Linux keyring, so the exact key mismatch on this machine is inferred from the code and failure, not independently proven.
Recovery verified: I backed up the existing AppImage and encrypted connection catalog, installed the official .3386 x86_64 AppImage after SHA-256 verification, and restarted the desktop app. The server then reported 0.1.1-nightly.20261020.3386; four post-restart catalog reads succeeded with zero failures, and the user confirmed that projects and environments reappeared. The catalog and database were not edited directly.
This adds a Linux reproduction to the Mac reports. A regression test should cover an existing Linux Nightly catalog across the .3386 → .3399 identity change and verify that local and saved remote environments remain visible after update.
Investigated with t3 triage by OpenAI Codex (GPT-6).
Same failure here on macOS arm64 (Darwin 27.0), updating Nightly 0.1.1-nightly.20261019.3373 → 0.1.1-nightly.20261020.3399. I can pin down the key mismatch:
Login Keychain before and after (metadata only):
t3code Safe Storage / account t3code Key: created 2026-08-16. This is the key the catalog was encrypted with.
T3 Code (Nightly) Safe Storage / account T3 Code (Nightly) Key: created 2026-10-20 08:13:20Z, the first launch of 3399.
Why: the packaged nightly's app.asar/package.json has "name": "t3code" and no productName. Before #20907, Chromium's OSCrypt therefore initialised under the name t3code. In 3399, DesktopPreReadyPlatform pins resolveDesktopSafeStorageName() = "T3 Code (Nightly)", which creates a fresh key. DesktopSafeStorageIdentity.decryptWithPreviousName returns None unless the pinned name is "T3 Code (Alpha)" (apps/desktop/src/app/DesktopSafeStorageIdentity.ts:29-33). Even then it only tries T3 Code (Beta) Safe Storage, so nightly installs whose catalog sits under t3code Safe Storage get no fallback.
Trace (desktop.trace.ndjson, on every launch of 3399):
desktop.safeStorageIdentity.decryptWithPreviousName Success (None)
desktop.connectionCatalogStore.recoverPreviousIdentityCatalog Failure
DesktopConnectionCatalogStoreProtectionError: … decrypt-catalog
ElectronSafeStorageDecryptError → Error while decrypting the ciphertext provided to safeStorage.decryptString.
web.connectionStorage.loadCatalog ConnectionTransientError
The database was intact (about 1.8k threads); only the catalog was unreadable. Recovery left connection-catalog.json untouched (still written by 3373), so a fixed build can still recover it.
Suggested fix direction: have the fallback try t3code Safe Storage (and probably the old app.getName() value generally) for every channel, not just Alpha → Beta. Stable installs whose packaged name was also t3code may have the same exposure. I haven't verified that.
Workaround that worked: reinstalling 0.1.1-nightly.20261019.3373 from Releases. It decrypts the untouched catalog and accepts the 65/66 migrations with only a divergence warning.
Diagnosed via t3 triage with Claude Opus 5.5 in Claude Code.
Activity
t3dotgg commentedon Oct 20, 2026
Actively on it - so sorry!
titipakorn-th commentedon Oct 20, 2026
Revert back to a previous version for now.
deondejongh commentedon Oct 20, 2026
Second Mac Nightly install with the same failure. I think this pins down the key mismatch.
Diagnosis
t3code Safe Storage(accountt3code Key).app.setName(resolveDesktopSafeStorageName(...))before ready. For nightly builds that returnsT3 Code (Nightly).T3 Code (Nightly) Safe Storage, at 08:12:24Z. The firstdecrypt-catalogfailure is in the same second.decryptWithPreviousNameonly runs when the current name isT3 Code (Alpha), and it only tries theT3 Code (Beta)key. Nightly has no fallback, so the oldt3codekey is never tried.T3 Code (Nightly)". On this Mac, noT3 Code (Nightly) Safe Storageitem existed before today. The only other T3 item ist3code Safe Storage, so that is very likely the key the old catalog uses. I have not yet confirmed this by decrypting with it.Suggested fix
On macOS/Linux nightly, when the catalog fails to decrypt, also try the
t3code Safe Storage/t3code Keykey, then re-encrypt with the new key, the same way the Beta fallback works.Version
Last good: 0.1.1-nightly.20261020.3386. First bad: 0.1.1-nightly.20261020.3399.
Environment
macOS (Darwin 27.0.0), Apple Silicon, desktop app with its local server.
Evidence
Workaround
Not run yet: quit the app, decrypt the catalog with the
t3code Safe Storagekey, and re-encrypt it with theT3 Code (Nightly) Safe Storagekey. I'll report back if it works.Filed by: Claude Code (claude-opus-5-5), following the
t3 triageplaybook.t3dotgg commentedon Oct 20, 2026
Warning
Update: #20907 was reverted in #22219. The next Nightly build goes back to the old
t3codekey.connection-catalog.json.bak-<number>in~/.t3/userdata) back overconnection-catalog.json. That backup uses the old key..3399must sign in to T3 Connect again: the Clerk session (clerk-tokens.json) uses the same key and is lost.Confirmed on a second Mac (desktop, Nightly
0.1.1-nightly.20261020.3399, macOS arm64). This is a regression from #20907. The data is not lost: the local server and database are fine. Only the saved connection catalog is unreadable, so no local or remote environment loads.Cause
t3code, so its key was the Keychain itemt3code Safe Storage.T3 Code (Nightly)before ready. On the first launch of the new build, Chromium created a newT3 Code (Nightly) Safe Storagekey. Its Keychain creation time is the same second as that launch.DesktopSafeStorageIdentity.decryptWithPreviousNameruns only when the name isT3 Code (Alpha), and it only tries the Beta key. So Nightly has no recovery path.connection-catalog.jsondecrypts with thet3codekey to a valid catalog, and fails with theT3 Code (Nightly)key.Workaround (macOS)
This script decrypts the catalog with the old key and encrypts it again with the new Nightly key. It makes a backup first and changes nothing unless an old key works. It needs no installs: it uses the app's bundled Electron as Node and the built-in
securitytool.fix-t3-nightly.sh. Do not paste it directly into your shell.bash fix-t3-nightly.sh.fix-t3-nightly.sh
Linux is not covered by this script. A fix PR is in progress.
Diagnosed with
t3 triageby Claude Opus 5.5 in Claude Code.hkarlsen06 commentedon Oct 20, 2026
I also noticed this. Got scared for a little second, before bunx t3 triage reassured me everything would be fine;)
Nsttt commentedon Oct 20, 2026
Thanks @t3dotgg, confirmed that fixes it.
juliusmarminge commentedon Oct 20, 2026
41b513d
tears-mysthrala commentedon Oct 20, 2026
Confirmed the same regression on Linux x64 (Arch, kernel 7.2.11-arch1-1), using the desktop AppImage and its local server.
Reproduction: From an existing Nightly installation with projects and saved environments, I used the update button in the desktop app. The affected server reported
0.1.1-nightly.20261020.3399. After the update, the desktop showed no projects or other environments. Signing in to T3 Connect again did not restore them.Local evidence (redacted):
desktop.trace.ndjsonrecordedDesktopConnectionCatalogStoreProtectionErrorduringdecrypt-catalogindesktop.connectionCatalogStore.getanddesktop.connectionCatalogStore.recoverPreviousIdentityCatalogat approximately 08:28 and 08:31 UTC on 20 October. The catalog IPC read failed too./.well-known/t3/environmentand reported build.3399before rollback..3399source only tries previous-name recovery forT3 Code (Alpha)and the Beta key; it has no Nightly fallback. This is consistent with the encryption-identity regression diagnosed above. I did not inspect or test the Linux keyring, so the exact key mismatch on this machine is inferred from the code and failure, not independently proven.Recovery verified: I backed up the existing AppImage and encrypted connection catalog, installed the official
.3386x86_64 AppImage after SHA-256 verification, and restarted the desktop app. The server then reported0.1.1-nightly.20261020.3386; four post-restart catalog reads succeeded with zero failures, and the user confirmed that projects and environments reappeared. The catalog and database were not edited directly.This adds a Linux reproduction to the Mac reports. A regression test should cover an existing Linux Nightly catalog across the
.3386→.3399identity change and verify that local and saved remote environments remain visible after update.Investigated with
t3 triageby OpenAI Codex (GPT-6).q1 commentedon Oct 20, 2026
insane response time, fixes it for me too
rgrvlsk commentedon Oct 20, 2026
Same failure here on macOS arm64 (Darwin 27.0), updating Nightly
0.1.1-nightly.20261019.3373→0.1.1-nightly.20261020.3399. I can pin down the key mismatch:Login Keychain before and after (metadata only):
t3code Safe Storage/ accountt3code Key: created 2026-08-16. This is the key the catalog was encrypted with.T3 Code (Nightly) Safe Storage/ accountT3 Code (Nightly) Key: created 2026-10-20 08:13:20Z, the first launch of 3399.Why: the packaged nightly's
app.asar/package.jsonhas"name": "t3code"and noproductName. Before #20907, Chromium's OSCrypt therefore initialised under the namet3code. In 3399,DesktopPreReadyPlatformpinsresolveDesktopSafeStorageName()="T3 Code (Nightly)", which creates a fresh key.DesktopSafeStorageIdentity.decryptWithPreviousNamereturnsNoneunless the pinned name is"T3 Code (Alpha)"(apps/desktop/src/app/DesktopSafeStorageIdentity.ts:29-33). Even then it only triesT3 Code (Beta) Safe Storage, so nightly installs whose catalog sits undert3code Safe Storageget no fallback.Trace (
desktop.trace.ndjson, on every launch of 3399):The database was intact (about 1.8k threads); only the catalog was unreadable. Recovery left
connection-catalog.jsonuntouched (still written by 3373), so a fixed build can still recover it.Suggested fix direction: have the fallback try
t3code Safe Storage(and probably the oldapp.getName()value generally) for every channel, not just Alpha → Beta. Stable installs whose packaged name was alsot3codemay have the same exposure. I haven't verified that.Workaround that worked: reinstalling
0.1.1-nightly.20261019.3373from Releases. It decrypts the untouched catalog and accepts the 65/66 migrations with only a divergence warning.Diagnosed via
t3 triagewith Claude Opus 5.5 in Claude Code.alexaka1 commentedon Oct 20, 2026
The new nightly restored everything for me.