Files
hikari-desktop/DEBUGGING.md
T
hikari 80ee25fa09 docs: add comprehensive debugging guide for common issues
Created DEBUGGING.md to document:
- Permission modal troubleshooting (NOT z-index!)
- Config loss prevention and fixes
- Event listener debugging
- Testing checklist
- Emergency recovery procedures

This should prevent us from going through the same debugging nightmare twice.
2026-02-06 22:38:11 -08:00

7.7 KiB

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():

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

// ❌ 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:
    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:

// ✅ 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:

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:

ls -la ~/.config/hikari-desktop/config.json

Should be writable by user:

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

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:

// ✅ 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:

.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:

console.log("[Tauri Listener] Setting up claude:permission listener");
const permissionUnlisten = await listen<PermissionPromptEvent>("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

pnpm check

Common fixes:

  • Missing imports
  • Wrong types
  • Calling non-existent methods

Rust Errors

cargo build --release

Common fixes:

  • Missing dependencies in Cargo.toml
  • Import path issues
  • Type mismatches

Full Clean Build

# 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:

    git log --oneline -5
    
  2. Revert to last working commit:

    git reset --hard <commit-hash>
    
  3. Clean build:

    rm -rf node_modules dist .svelte-kit src-tauri/target
    pnpm install
    pnpm build
    
  4. Reset config:

    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