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: Tauri events never reach frontend — require() fails in ESM/Vite context, falls back to DOM listeners #462
Claude runs perfectly (backend works), but the frontend never receives any Tauri events — resulting in infinite loading spinner, no response shown, cancel button broken (claudeSessionId stays null).
Root Cause
ClaudeCodeSession.tsx loads the Tauri event listener via require() inside a try/catch:
// src/components/ClaudeCodeSession.tsxlettauriListen: any;try{if(typeofwindow!=='undefined'&&window.__TAURI__){tauriListen=require("@tauri-apps/api/event").listen;// ← BUG}}catch(e){console.log('[ClaudeCodeSession] Tauri APIs not available, using web mode');}constlisten=tauriListen||domEventFallback;
Vite bundles as ESM — require is not defined at runtime → ReferenceError is thrown → silently caught → tauriListen stays undefined → listen = DOM event fallback.
The DOM fallback listens via window.addEventListener(eventName, ...) and expects window.dispatchEvent(new CustomEvent(...)). But the Rust backend emits events through Tauri's IPC bridge, not the DOM — so the frontend receives zero events.
Symptoms
Infinite loading animation after sending a message
No response rendered (though Claude responds correctly — verified via RUST_LOG=debug)
Cancel button does nothing (requires claudeSessionId which is set from the init event — never received)
All macOS (and likely Linux) users building from source with Vite. The require() anti-pattern in ESM is the culprit.
Fix
Replace the require() pattern with a proper static ESM import:
- let tauriListen: any;- try {- if (typeof window !== 'undefined' && window.__TAURI__) {- tauriListen = require("@tauri-apps/api/event").listen;- }- } catch (e) {- console.log('[ClaudeCodeSession] Tauri APIs not available, using web mode');- }-- const listen = tauriListen || ((eventName, callback) => {- window.addEventListener(eventName, ...);- return Promise.resolve(...);- });+ import { listen } from "@tauri-apps/api/event";
One line. Fixes all event delivery.
Verification
After the fix, the debug overlay shows correct progression:
Before send: loading:false | sid:null | msgs:0 | listening:false
After response: loading:false | sid:d49637f9 | msgs:3 | listening:false
Claude responses render correctly and loading state clears.
Notes
The same require() pattern exists in useClaudeMessages.ts (for claude-stream events) — worth fixing there too for consistency, though that code path may not be active by default.
Activity
fix: replace require() with static ESM import for Tauri event API