fix(desktop): prevent IPC ID collisions with global operation ID counter#712
fix(desktop): prevent IPC ID collisions with global operation ID counter#712
Conversation
📝 WalkthroughWalkthroughAdds exported auth types ( Changes
Sequence Diagram(s)sequenceDiagram
participant UI as React Component
participant ReactClient as reactClient (trpc)
participant SessionLink as sessionIdLink
participant Ipc as ipcLink / IPC
participant Main as Main Process / trpc server
UI->>ReactClient: invoke query/mutation (hooks)
ReactClient->>SessionLink: attach global operation id
SessionLink->>Ipc: forward request with id
Ipc->>Main: send IPC message
Main->>Main: route to appropriate router (e.g., auth)
Main-->>Ipc: send response
Ipc-->>SessionLink: deliver response (matches by id)
SessionLink-->>ReactClient: forward response
ReactClient-->>UI: update hook state
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @apps/desktop/src/renderer/lib/trpc-client.ts:
- Around line 1-4: Remove the unused AppRouter type import from the top-level
import list: delete "AppRouter" from the import statement so only the actually
used modules (superjson, ipcLink, trpc) are imported; verify there are no other
references to AppRouter in this file (the trpc instance from ./trpc already
carries the type), then run a quick TypeScript/ESLint check to ensure the unused
import warning is resolved.
🧹 Nitpick comments (3)
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsx (1)
1-4: Consider using alias import for consistency.Line 2 uses the alias
lib/trpcwhile line 4 uses a relative path../../lib/trpc-client. For consistency and per coding guidelines, consider using the alias if configured.-import { trpcClient } from "../../lib/trpc-client"; +import { trpcClient } from "lib/trpc-client";apps/desktop/src/main/lib/auth/auth.ts (1)
227-229: Consider logging the error instead of silently swallowing it.Per coding guidelines, errors should not be swallowed silently. While it's understandable that the file may not exist, logging at debug level would aid troubleshooting.
try { await fs.unlink(TOKEN_FILE); - } catch {} + } catch (error) { + // File may not exist, which is fine during signOut + console.log("[auth] Token file cleanup:", error instanceof Error ? error.message : "unknown error"); + }apps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsx (1)
5-6: Consider importingAuthStatefrom the canonical source.The
AuthStatetype is already exported fromapps/desktop/src/lib/trpc/routers/auth/index.ts. Importing it directly would ensure type consistency and avoid potential drift if the router type changes.♻️ Suggested refactor
import { createContext, type ReactNode, useContext } from "react"; -import type { RouterOutputs } from "../../lib/trpc"; +import type { AuthState } from "@/lib/trpc/routers/auth"; import { trpc } from "../../lib/trpc"; - -type AuthState = RouterOutputs["auth"]["onAuthState"];
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
apps/desktop/src/lib/trpc/routers/auth/index.tsapps/desktop/src/main/lib/auth/auth.tsapps/desktop/src/main/lib/auth/index.tsapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)
apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined insrc/lib/trpc
Use alias as defined intsconfig.jsonwhen possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from@trpc/server/observableinstead of async generators, as the library explicitly checksisObservable(result)and throws an error otherwise
Files:
apps/desktop/src/lib/trpc/routers/auth/index.tsapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/main/lib/auth/auth.tsapps/desktop/src/main/lib/auth/index.tsapps/desktop/src/renderer/lib/trpc-client.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use object parameters for functions with 2+ parameters instead of positional arguments
Functions with 2+ parameters should accept a single params object with named properties for self-documentation and extensibility
Use prefixed console logging with context pattern: [domain/operation] message
Extract magic numbers and hardcoded values to named constants at module top
Use lookup objects/maps instead of repeated if (type === ...) conditionals
Avoid usinganytype - maintain type safety in TypeScript code
Never swallow errors silently - at minimum log them with context
Import from concrete files directly when possible - avoid barrel file abuse that creates circular dependencies
Avoid deep nesting (4+ levels) - use early returns, extract functions, and invert conditions
Use named properties in options objects instead of boolean parameters to avoid boolean blindness
Files:
apps/desktop/src/lib/trpc/routers/auth/index.tsapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/main/lib/auth/auth.tsapps/desktop/src/main/lib/auth/index.tsapps/desktop/src/renderer/lib/trpc-client.ts
apps/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Drizzle ORM for all database operations - never use raw SQL
Files:
apps/desktop/src/lib/trpc/routers/auth/index.tsapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/main/lib/auth/auth.tsapps/desktop/src/main/lib/auth/index.tsapps/desktop/src/renderer/lib/trpc-client.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome for formatting and linting - run at root level with
bun run lint:fixorbiome check --write
Files:
apps/desktop/src/lib/trpc/routers/auth/index.tsapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/main/lib/auth/auth.tsapps/desktop/src/main/lib/auth/index.tsapps/desktop/src/renderer/lib/trpc-client.ts
apps/desktop/src/renderer/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility
Files:
apps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
One component per file - do not create multi-component files
Files:
apps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsx
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
Applied to files:
apps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsx
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`
Applied to files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/api/**/*.{ts,tsx} : Use TRPCError with appropriate error codes: NOT_FOUND, UNAUTHORIZED, FORBIDDEN, BAD_REQUEST, INTERNAL_SERVER_ERROR, NOT_IMPLEMENTED
Applied to files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from `trpc/server/observable` instead of async generators, as the library explicitly checks `isObservable(result)` and throws an error otherwise
Applied to files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/api/**/*.{ts,tsx} : Extract business logic from tRPC procedures into utility functions when logic exceeds ~50 lines, is used by multiple procedures, or needs independent testing
Applied to files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/desktop/src/renderer/**/*.{ts,tsx} : Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility
Applied to files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Use alias as defined in `tsconfig.json` when possible
Applied to files:
apps/desktop/src/main/lib/auth/auth.tsapps/desktop/src/main/lib/auth/index.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/api/**/*.{ts,tsx} : tRPC procedures and API route handlers should validate and delegate; keep orchestrators thin
Applied to files:
apps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/desktop/src/lib/*.ts : Never import Node.js modules in shared code like electron-router-dom.ts - it runs in both main and renderer processes
Applied to files:
apps/desktop/src/renderer/lib/trpc-client.ts
🧬 Code graph analysis (2)
apps/desktop/src/lib/trpc/routers/auth/index.ts (3)
apps/desktop/src/main/lib/auth/auth.ts (1)
AuthSession(50-50)apps/desktop/src/lib/trpc/index.ts (1)
router(47-47)packages/trpc/src/index.ts (1)
publicProcedure(12-12)
apps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsx (1)
apps/desktop/src/lib/trpc/routers/auth/index.ts (1)
AuthState(8-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Cursor Bugbot
- GitHub Check: Build
🔇 Additional comments (7)
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsx (1)
23-27: LGTM! Correctly uses the shared tRPC client.This change properly addresses the IPC ID collision issue by using the shared
trpcClientinstance instead of creating a separate client. The single client ensures consistent ID counters across all tRPC operations.apps/desktop/src/main/lib/auth/index.ts (1)
1-2: LGTM! Clean type re-export.The addition of
AuthSessionto the public API surface correctly exposes the session type needed by the auth router and other consumers.apps/desktop/src/lib/trpc/routers/auth/index.ts (2)
7-8: LGTM! Well-defined auth state type.The
AuthStatetype correctly captures the union of authenticated state (session + token) and unauthenticated state (null). The JSDoc comment provides helpful context.
12-42: LGTM! Subscription correctly typed and implemented.The observable pattern is correctly used per coding guidelines for trpc-electron. The
AuthStategeneric ensures subscribers receive properly typed data, addressing the original bug where auth subscriptions received incorrect shapes like{success: true}.apps/desktop/src/renderer/lib/trpc-client.ts (1)
6-19: LGTM! Well-documented single client implementation.The change correctly consolidates tRPC client creation to prevent IPC ID collisions. The documentation clearly explains the rationale and usage patterns. Using
trpc.createClient(from the typedcreateTRPCReactinstance) ensures compatibility with both React hooks and imperative calls.apps/desktop/src/main/lib/auth/auth.ts (1)
48-51: LGTM! Correct type extraction from API response.The type chain properly extracts session data:
SessionResponsecaptures the full{data, error}responseAuthSessionextracts only thedataproperty, excluding nullSessionprovides a local aliasThis correctly addresses the bug where
AuthSessionpreviously included the full wrapper.apps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsx (1)
14-23: LGTM! Clean simplification of the auth context provider.The inline value computation with optional chaining and nullish coalescing correctly handles the undefined state before the subscription emits. The type alignment with
AuthStateproperly reflects that the session can be null, fixing the type extraction issue mentioned in the PR objectives.
The app has two tRPC clients:
- React client (for hooks via TRPCProvider)
- Proxy client (for imperative calls from stores/utilities)
Each ipcLink creates its own IPCClient with a separate ID counter.
When both clients used separate ipcLinks, operations could get the same
ID, causing responses to be misrouted (e.g., mutation response
{success: true} going to a subscription).
Fix: Create a single shared ipcLink instance used by both clients.
This ensures all operations get unique IDs from the same counter.
Also fixes AuthSession type to correctly extract session data from
the API response (was including the full {data, error} wrapper).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
b9a6d5b to
fccc6c7
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsx (1)
5-6: Consider importingAuthStatedirectly from the router.The local type alias duplicates the
AuthStatetype already exported fromapps/desktop/src/lib/trpc/routers/auth/index.ts. While usingRouterOutputsis idiomatic for tRPC and will stay in sync, importing the explicit type could improve clarity and reduce duplication.♻️ Optional: Import AuthState directly
import { createContext, type ReactNode, useContext } from "react"; -import type { RouterOutputs } from "../../lib/trpc"; +import type { AuthState } from "../../lib/trpc/routers/auth"; import { trpc } from "../../lib/trpc"; - -type AuthState = RouterOutputs["auth"]["onAuthState"];
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
apps/desktop/src/lib/trpc/routers/auth/index.tsapps/desktop/src/main/lib/auth/auth.tsapps/desktop/src/main/lib/auth/index.tsapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/desktop/src/main/lib/auth/auth.ts
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)
apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined insrc/lib/trpc
Use alias as defined intsconfig.jsonwhen possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from@trpc/server/observableinstead of async generators, as the library explicitly checksisObservable(result)and throws an error otherwise
Files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/lib/trpc/routers/auth/index.tsapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/lib/trpc-client.tsapps/desktop/src/main/lib/auth/index.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use object parameters for functions with 2+ parameters instead of positional arguments
Functions with 2+ parameters should accept a single params object with named properties for self-documentation and extensibility
Use prefixed console logging with context pattern: [domain/operation] message
Extract magic numbers and hardcoded values to named constants at module top
Use lookup objects/maps instead of repeated if (type === ...) conditionals
Avoid usinganytype - maintain type safety in TypeScript code
Never swallow errors silently - at minimum log them with context
Import from concrete files directly when possible - avoid barrel file abuse that creates circular dependencies
Avoid deep nesting (4+ levels) - use early returns, extract functions, and invert conditions
Use named properties in options objects instead of boolean parameters to avoid boolean blindness
Files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/lib/trpc/routers/auth/index.tsapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/lib/trpc-client.tsapps/desktop/src/main/lib/auth/index.ts
apps/desktop/src/renderer/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility
Files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
One component per file - do not create multi-component files
Files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsx
apps/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Drizzle ORM for all database operations - never use raw SQL
Files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/lib/trpc/routers/auth/index.tsapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/lib/trpc-client.tsapps/desktop/src/main/lib/auth/index.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome for formatting and linting - run at root level with
bun run lint:fixorbiome check --write
Files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/lib/trpc/routers/auth/index.tsapps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsxapps/desktop/src/renderer/lib/trpc-client.tsapps/desktop/src/main/lib/auth/index.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`
Applied to files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/api/**/*.{ts,tsx} : Use TRPCError with appropriate error codes: NOT_FOUND, UNAUTHORIZED, FORBIDDEN, BAD_REQUEST, INTERNAL_SERVER_ERROR, NOT_IMPLEMENTED
Applied to files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/api/**/*.{ts,tsx} : Extract business logic from tRPC procedures into utility functions when logic exceeds ~50 lines, is used by multiple procedures, or needs independent testing
Applied to files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from `trpc/server/observable` instead of async generators, as the library explicitly checks `isObservable(result)` and throws an error otherwise
Applied to files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/desktop/src/renderer/**/*.{ts,tsx} : Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility
Applied to files:
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsxapps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
Applied to files:
apps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsx
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/desktop/src/shared/ipc-channels.ts : Define IPC channel types in apps/desktop/src/shared/ipc-channels.ts before implementing handlers
Applied to files:
apps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/desktop/src/lib/*.ts : Never import Node.js modules in shared code like electron-router-dom.ts - it runs in both main and renderer processes
Applied to files:
apps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/desktop/src/main/lib/*-ipcs.ts : IPC handlers must accept a single object parameter, not positional parameters
Applied to files:
apps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/desktop/src/lib/electron-router-dom.ts : Do not import Node.js modules like node:path or dotenv in electron-router-dom.ts and similar shared files - they run in both main and renderer processes
Applied to files:
apps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/api/**/*.{ts,tsx} : tRPC procedures and API route handlers should validate and delegate; keep orchestrators thin
Applied to files:
apps/desktop/src/renderer/lib/trpc-client.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/**/proxy.ts : Never use `middleware.ts` in Next.js 16. Use `proxy.ts` instead for request interception.
Applied to files:
apps/desktop/src/renderer/lib/trpc-client.ts
🧬 Code graph analysis (4)
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsx (1)
apps/desktop/src/renderer/lib/trpc-client.ts (1)
reactClient(20-22)
apps/desktop/src/lib/trpc/routers/auth/index.ts (4)
apps/desktop/src/main/lib/auth/auth.ts (1)
AuthSession(50-50)apps/desktop/src/lib/trpc/index.ts (1)
router(47-47)packages/trpc/src/trpc.ts (1)
publicProcedure(31-31)packages/trpc/src/index.ts (1)
publicProcedure(12-12)
apps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsx (1)
apps/desktop/src/lib/trpc/routers/auth/index.ts (1)
AuthState(8-8)
apps/desktop/src/renderer/lib/trpc-client.ts (1)
apps/desktop/src/lib/trpc/routers/index.ts (1)
AppRouter(47-47)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Cursor Bugbot
- GitHub Check: Build
🔇 Additional comments (6)
apps/desktop/src/renderer/contexts/TRPCProvider/TRPCProvider.tsx (1)
1-27: LGTM! Clean consolidation to shared tRPC client.The refactor correctly addresses the IPC ID collision bug by using the shared
reactClientinstead of creating a local client. TheQueryClientremains component-scoped (viauseState), which is correct for React Query's cache isolation per app instance.Based on learnings, this properly uses tRPC as defined in
src/lib/trpcfor Electron IPC.apps/desktop/src/renderer/lib/trpc-client.ts (1)
7-29: Excellent fix with clear documentation.The shared
ipcLinkapproach correctly solves the ID collision issue. The documentation on lines 7-14 is particularly valuable—it explains the root cause and why the sharing constraint exists, which will prevent future regressions.Both clients (
reactClientfor React hooks,trpcClientfor imperative calls) now share the same underlying IPC link and its ID counter, ensuring responses are routed to the correct operations.Based on learnings, this properly uses tRPC as defined in
src/lib/trpcfor Electron IPC.apps/desktop/src/main/lib/auth/index.ts (1)
1-2: LGTM!Clean addition of the
AuthSessiontype re-export alongside the existing exports. This properly exposes the corrected type for use in the auth router and other modules.apps/desktop/src/lib/trpc/routers/auth/index.ts (2)
7-8: LGTM - Well-defined AuthState type.The explicit
AuthStatetype cleanly combinesAuthSessionwith the token field. This provides a clear contract for subscription consumers and helps prevent the type confusion mentioned in the PR objectives.
12-43: LGTM - Subscription correctly uses observable pattern.The subscription properly uses
observable<AuthState>from@trpc/server/observable, which is required for trpc-electron compatibility. The cleanup function correctly unsubscribes from both event handlers.apps/desktop/src/renderer/contexts/AuthProvider/AuthProvider.tsx (1)
7-20: LGTM - Clean derivation of token and session from auth state.The context value correctly extracts
tokenandsessionfrom the subscription data with proper null handling. This aligns with the PR's fix for theAuthSessiontype to correctly extract session data from the API response.
The previous approach of sharing ipcLink doesn't work because each tRPC client still creates its own IPCClient instance when the link factory is called during initialization. The correct fix is to use a global operation ID counter (sessionIdLink) that replaces each operation's ID with a unique value from a shared counter. This ensures operations from both the React client and proxy client get distinct IDs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
Summary
Fixes bug where auth subscription received incorrect data (
{success: true}) from mutation responses due to IPC operation ID collisions.Root Cause
The app has two tRPC clients:
reactClient) - for hooks via TRPCProvidertrpcClient) - for imperative calls from stores/utilitiesEach tRPC client calls the
ipcLinkfactory during initialization, creating separate IPCClient instances. Each IPCClient:onMessagehandler (all handlers receive all IPC responses)#pendingRequestsmap keyed by operation IDWhen both clients have operations with the same ID, responses can be routed to the wrong client.
Solution
Add
sessionIdLinkthat replaces operation IDs with globally unique values from a shared counter. This ensures all operations across both clients get distinct IDs.Also Fixes
AuthSessiontype now correctly extracts session data from API response (was including the full{data, error}wrapper)AuthStatetype for subscription outputTest plan
{success: true}or other invalid shapes🤖 Generated with Claude Code
Note
Prevents IPC response misrouting between multiple tRPC clients by ensuring globally unique operation IDs.
sessionIdLinkthat replacesop.idwith a global counter and applies it to bothreactClientandtrpcClientTRPCProvidernow usesreactClientcreated inrenderer/lib/trpc-clientAuthSession, addsAuthStateforonAuthState, and updatesAuthProviderto use the new typesWritten by Cursor Bugbot for commit 39543c0. This will update automatically on new commits. Configure here.