Skip to content

fix(desktop): recover corrupt connection catalog documents - #5902

Closed
nickmatteo wants to merge 1 commit into
pingdotgg:mainfrom
nickmatteo:fix/catalog-document-recovery-4750
Closed

nickmatteo wants to merge 1 commit into
pingdotgg:mainfrom
nickmatteo:fix/catalog-document-recovery-4750

Conversation

@nickmatteo

@nickmatteo nickmatteo commented Aug 9, 2026 •

Copy link
Copy Markdown

Fixes #4750.

A malformed outer connection-catalog.json document currently aborts the desktop catalog read before T3 Code can reach its existing missing-catalog and legacy-migration behavior. On Windows, a power-loss-corrupted document can therefore prevent the app from starting normally on every subsequent launch.

The current catalog writer already writes a temporary sibling and renames it into place, so this PR intentionally does not replace or claim to introduce atomic writes. Instead, it catches only DesktopConnectionCatalogStoreDocumentDecodeError, moves the malformed document to a unique same-directory connection-catalog.json.corrupt.<pid>.<uuid> sibling, logs sanitized metadata, and treats the active catalog as missing. If quarantine itself fails, recovery remains best effort and startup can still proceed.

Filesystem read and permission errors, invalid encrypted payload base64, safe-storage availability failures, and decryption failures continue to surface normally and leave the active catalog untouched.

Validation:

  • pnpm exec vp test run apps/desktop/src/app/DesktopConnectionCatalogStore.test.ts --reporter=dot — 11 tests passed
  • pnpm exec vp run --filter @t3tools/desktop typecheck
  • pnpm exec vp lint apps/desktop/src/app/DesktopConnectionCatalogStore.ts apps/desktop/src/app/DesktopConnectionCatalogStore.test.ts --report-unused-disable-directives
  • pnpm exec vp fmt --check apps/desktop/src/app/DesktopConnectionCatalogStore.ts apps/desktop/src/app/DesktopConnectionCatalogStore.test.ts
  • git show --check HEAD

Built with GPT-5.6-Sol through the Codex harness in T3 Code.

Note

Recover corrupt connection catalog documents by quarantining them instead of failing

  • When DesktopConnectionCatalogStore.get encounters a corrupt (undecodable) catalog file, it now renames the file to a quarantine path (<catalog>.corrupt.<pid>.<hex32>) and returns Option.none instead of propagating a decode error.
  • If the rename itself fails, the corrupt file is left in place, a structured warning is logged (without sensitive content), and Option.none is still returned.
  • Behavioral Change: callers that previously received a DesktopConnectionCatalogStoreDocumentDecodeError on corrupt catalogs will now receive an empty result, treating the catalog as missing.

Macroscope summarized 4832a47.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4a12c536-d469-4e30-af54-c881e57be0c3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 9, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One convention violation found in apps/desktop/src/app/DesktopConnectionCatalogStore.ts: recovery of the known decode failure uses Effect.catchTag instead of Effect.catchTags.

Posted via Macroscope — Effect Service Conventions

});

const readRecoverableDocument = readDocument(fileSystem, catalogPath).pipe(
Effect.catchTag("DesktopConnectionCatalogStoreDocumentDecodeError", (decodeError) =>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Statically known tagged failures should be recovered with Effect.catchTags({ ... }), even when only one tag is handled; Effect.catchTag isn't used in this codebase's conventions.

Consider switching to the object form:

-    Effect.catchTag("DesktopConnectionCatalogStoreDocumentDecodeError", (decodeError) =>
-      Effect.gen(function* () {
+    Effect.catchTags({
+      DesktopConnectionCatalogStoreDocumentDecodeError: (decodeError) =>
+        Effect.gen(function* () {

and close it with }), → }, plus the matching brace for the object (the body indentation shifts one level).

Posted via Macroscope — Effect Service Conventions

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as part of the open-PR backlog sweep (wave 1).

Reason: Abandoned draft; no movement since August 9

Reopen if this is still wanted and you’re willing to rebase onto current main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

connection-catalog.json is written non-atomically every ~3s, and a corrupt document bricks the app permanently

2 participants