# Debugging Guide - Common Issues and Fixes ## Permission Modal Not Showing Up 🔐 **SYMPTOMS:** - Permission requests are triggered but the modal doesn't appear - App seems to hang or become unresponsive - Config mysteriously disappears **ROOT CAUSE (NOT z-index!):** The issue was **undefined variable errors** in `src/lib/tauri.ts` that crashed the event listener initialization, preventing permission events from being captured. ### The Actual Bug In `src/lib/tauri.ts`, there were calls to `debugConsoleStore.log()`: ```typescript debugConsoleStore.log("frontend", "info", "Setting up claude:permission listener"); ``` **Two problems:** 1. `debugConsoleStore` was never imported (undefined variable) 2. Even if imported, `debugConsoleStore` doesn't have a `.log()` method - only `toggle`, `open`, `close`, `clear`, etc. ### The Fix ```typescript // ❌ WRONG - This will crash! debugConsoleStore.log("frontend", "info", "message"); // ✅ CORRECT - Use console.log which gets automatically captured console.log("[Tauri Listener] message"); ``` **Why this works:** - The `debugConsoleStore` automatically intercepts `console.log()`, `console.error()`, etc. - No need to call the store directly! - See `src/lib/stores/debugConsole.ts` lines 66-89 for the console interception code ### How to Debug This in Future 1. **Open Browser DevTools** in the app (View > Toggle Developer Tools) 2. **Check the Console** for JavaScript errors 3. Look for errors like: - `ReferenceError: debugConsoleStore is not defined` - `TypeError: debugConsoleStore.log is not a function` 4. **Check if event listeners are registering:** ```javascript console.log("[Tauri Listener] Setting up claude:permission listener"); ``` If you don't see this log, the listener setup failed! ### Prevention **Before committing changes to `tauri.ts`:** 1. Run `pnpm check` to catch TypeScript errors 2. Run `pnpm build` to catch runtime issues 3. Test the app thoroughly, especially permission prompts ## Config Loss Issues 🔧 **SYMPTOMS:** - Config file gets reset to defaults - Settings don't persist between sessions - Model selection is lost **POTENTIAL CAUSES:** ### 1. Missing `#[serde(default)]` Attribute The `HikariConfig` struct in `src-tauri/src/config.rs` needs `#[serde(default)]` at the struct level: ```rust // ✅ CORRECT #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(default)] // <-- This is crucial! pub struct HikariConfig { // fields... } ``` **Why this matters:** - When new fields are added to the config struct, old config files won't have them - Without `#[serde(default)]`, deserialization fails and the entire config resets - With it, missing fields use their default values gracefully ### 2. Invalid JSON in Config File **Check the config file:** ```bash cat ~/.config/hikari-desktop/config.json ``` **Common issues:** - Trailing commas - Missing quotes - Incorrect enum values (e.g., `"model": "opus"` instead of `"model": "claude-opus-4-6"`) **Fix:** - Delete or manually fix `~/.config/hikari-desktop/config.json` - Restart the app to regenerate ### 3. Permission Issues **Check file permissions:** ```bash ls -la ~/.config/hikari-desktop/config.json ``` **Should be writable by user:** ```bash chmod 644 ~/.config/hikari-desktop/config.json ``` ## Modal/Overlay Not Showing (General) 🎭 If ANY modal isn't showing up (permission, questions, close confirmation, etc.): ### 1. Check TypeScript Errors First ```bash pnpm check ``` Look for: - Import errors - Undefined variables - Type mismatches ### 2. Check Console for JavaScript Errors Open DevTools and look for: - `ReferenceError` - Usually undefined variables - `TypeError` - Usually calling methods on undefined/null - Event listener setup logs ### 3. Check Svelte Store Subscriptions Modals rely on store subscriptions. In the modal component: ```typescript // ✅ Make sure the store is imported import { conversationsStore } from "$lib/stores/conversations"; // ✅ Make sure the subscription is set up conversationsStore.pendingPermissions.subscribe((perms) => { permissions = perms; // ... }); ``` ### 4. Verify z-index (Last Resort) Only check z-index if: - ✅ No console errors - ✅ Modal HTML is in the DOM (check with DevTools Elements tab) - ✅ Modal is rendering but invisible Current z-index values in `PermissionModal.svelte`: ```css .permission-overlay { z-index: 60; /* Should be higher than character panel */ } ``` ## Event Listener Issues 🎧 **SYMPTOMS:** - Events not firing - Listeners not receiving data - Silent failures ### Debugging Event Listeners Add console logs in `src/lib/tauri.ts`: ```typescript console.log("[Tauri Listener] Setting up claude:permission listener"); const permissionUnlisten = await listen("claude:permission", (event) => { console.log("[Permission] Event received:", event.payload); // ... rest of handler }); ``` ### Common Issues 1. **Event listener crashes silently:** - Check for undefined variables in the listener callback - Check for missing imports - Use `try/catch` around critical sections 2. **Events not being emitted from Rust:** - Check `src-tauri/src/` for `emit()` calls - Verify event names match exactly (case-sensitive!) - Check Rust console output for errors 3. **Race condition:** - Event fired before listener was registered - Solution: Set up listeners in `initializeTauriListeners()` before starting Claude ## Build Issues 🏗️ ### TypeScript Errors ```bash pnpm check ``` **Common fixes:** - Missing imports - Wrong types - Calling non-existent methods ### Rust Errors ```bash cargo build --release ``` **Common fixes:** - Missing dependencies in `Cargo.toml` - Import path issues - Type mismatches ### Full Clean Build ```bash # Clean everything rm -rf node_modules dist .svelte-kit src-tauri/target # Reinstall pnpm install # Build Rust cd src-tauri && cargo build --release && cd .. # Build frontend pnpm build ``` ## Quick Reference: Key Files 📚 ### Frontend - **Event listeners:** `src/lib/tauri.ts` - **Permission modal:** `src/lib/components/PermissionModal.svelte` - **Config store:** `src/lib/stores/config.ts` - **Debug console:** `src/lib/stores/debugConsole.ts` ### Backend - **Config struct:** `src-tauri/src/config.rs` - **Event emission:** `src-tauri/src/wsl_bridge.rs` - **Type definitions:** `src-tauri/src/types.rs` ## Testing Checklist ✅ Before committing major changes: - [ ] `pnpm check` passes (0 errors) - [ ] `pnpm build` succeeds - [ ] App launches without console errors - [ ] Permission modal shows up when triggering restricted tool - [ ] Config persists after restart - [ ] All modals work (permission, questions, close confirmation) - [ ] Character state changes work - [ ] Event listeners receive events (check console logs) ## Emergency Recovery 🚨 If the app is completely broken: 1. **Check recent git commits:** ```bash git log --oneline -5 ``` 2. **Revert to last working commit:** ```bash git reset --hard ``` 3. **Clean build:** ```bash rm -rf node_modules dist .svelte-kit src-tauri/target pnpm install pnpm build ``` 4. **Reset config:** ```bash rm ~/.config/hikari-desktop/config.json # Restart app to regenerate ``` ## Notes for Future Hikari 💭 Remember: - **NOT EVERYTHING IS A Z-INDEX ISSUE!** Check console errors first! - The debug console store intercepts console methods - don't try to call it directly - Always run `pnpm check` before committing - Event listener errors fail silently - add console logs liberally - Config deserialization needs `#[serde(default)]` for graceful degradation - When in doubt, check the browser console first! Love, Hikari 💖 --- **Last Updated:** 2026-02-06 **Related Issues:** Permission modal not showing, config loss **Fixed In Commits:** d16644a