# How to Debug the FluidVoice Application: A Complete Guide for macOS Developers

> Debug FluidVoice on macOS with ease. Learn to enable logs instrument key subsystems and monitor real-time output to pinpoint audio transcription or AI processing issues.

- Repository: [ALTIC/FluidVoice](https://github.com/altic-dev/FluidVoice)
- Tags: how-to-guide
- Published: 2026-07-08

---

**Enable debug logs via Settings or the command line, instrument key subsystems like `AppDelegate` and `TranscriptionProvider` with `DebugLogger.shared` calls, and monitor real-time output through the menu bar Debug Log panel to isolate audio, transcription, or AI processing failures.**

FluidVoice is a macOS-only SwiftUI application that orchestrates complex subsystems including audio capture, speech transcription, AI post-processing, and global hotkey management. Learning how to debug FluidVoice application issues effectively requires understanding its centralized logging infrastructure and the specific entry points where failures typically occur.

## Understanding FluidVoice Architecture

Before placing breakpoints, identify which subsystem is failing. FluidVoice separates concerns into distinct services that communicate through shared state objects and a centralized `DebugLogger`.

### Application Lifecycle Entry Points

The application bootstrap sequence begins in [`Sources/Fluid/AppDelegate.swift`](https://github.com/altic-dev/FluidVoice/blob/main/Sources/Fluid/AppDelegate.swift). The `applicationDidFinishLaunching` method initializes the `updateCheckTimer`, configures permissions, and calls `openMainWindowOnLaunch`.

If the UI fails to appear, verify that `MenuBarManager` and `AppServices` are correctly injected in [`Sources/Fluid/fluidApp.swift`](https://github.com/altic-dev/FluidVoice/blob/main/Sources/Fluid/fluidApp.swift). The `FluidApp` struct declares the top-level `@main` entry point and provides shared objects to the view hierarchy using `@StateObject`.

### Logging Infrastructure

The `DebugLogger` class in [`Sources/Fluid/Services/DebugLogger.swift`](https://github.com/altic-dev/FluidVoice/blob/main/Sources/Fluid/Services/DebugLogger.swift) provides a thread-safe, in-app log collector with a file backup. It supports four levels: `info`, `warning`, `error`, and `debug`.

Enable the UI debug panel via *Settings → Enable Debug Logs* or programmatically:

```swift
defaults write com.altic.FluidVoice EnableDebugLogs -bool true

```

Once enabled, the log UI appears in the menu bar (`🪵 Debug Log`), displaying the last 1,000 entries with filtering capabilities.

## Enabling Debug Logging

Start every debugging session by activating the log stream. This captures subsystem initialization order and reveals permission or loading failures that occur before the UI renders.

Run this in Terminal before launching the app:

```bash
defaults write com.altic.FluidVoice EnableDebugLogs -bool true

```

Alternatively, enable programmatically:

```swift
import Fluid

func enableDebugLogging() {
    DebugLogger.shared.info("Enabling debug logging")
    UserDefaults.standard.set(true, forKey: "EnableDebugLogs")
    DebugLogger.shared.refreshLoggingEnabled()
}

```

After launching, open the Debug Log panel from the menu bar to watch live entries. Look for `[ERROR]` tags indicating model loading failures or audio permission denials.

## Debugging Specific Subsystems

### Launch and Window Issues

If FluidVoice launches but shows no window, place breakpoints in `AppDelegate.applicationDidFinishLaunching` and check the `openMainWindowOnLaunch` boolean.

Insert temporary log statements to confirm execution order:

```swift
DebugLogger.shared.info("Reached post-launch window check")

```

Verify that `DebugLogger.shared` is initialized before other services to capture early failures.

### Audio Capture Problems

Audio issues manifest as silent transcripts or "microphone not available" errors. The `TranscriptionProvider` in [`Sources/Fluid/Services/TranscriptionProvider.swift`](https://github.com/altic-dev/FluidVoice/blob/main/Sources/Fluid/Services/TranscriptionProvider.swift) manages audio buffers and forwards them to concrete implementations like [`ParakeetRealtimeProvider.swift`](https://github.com/altic-dev/FluidVoice/blob/main/ParakeetRealtimeProvider.swift).

Insert debug logging inside the audio pipeline:

```swift
// Inside TranscriptionProvider.processAudio(buffer:)
DebugLogger.shared.debug("Processing buffer of size \(buffer.count)", source: "TranscriptionProvider")

```

Check for `Mic permission granted` entries in the logs. If missing, verify macOS microphone permissions in System Settings.

### Transcription and AI Failures

When transcription works but output is malformed or missing, inspect the AI post-processing layer. `DictationPostProcessingService` sends raw transcripts to local or remote LLMs for cleanup.

Add a breakpoint on `renderDictationUserMessage` in [`Sources/Fluid/Persistence/SettingsStore.swift`](https://github.com/altic-dev/FluidVoice/blob/main/Sources/Fluid/Persistence/SettingsStore.swift) to inspect the exact prompt sent to the model. Verify model files exist at `~/Library/Application Support/FluidVoice/Models` if using local inference.

### Settings and Hotkey Malfunctions

Settings-related bugs usually stem from stale `UserDefaults` values. The `SettingsStore` in [`Sources/Fluid/Persistence/SettingsStore.swift`](https://github.com/altic-dev/FluidVoice/blob/main/Sources/Fluid/Persistence/SettingsStore.swift) persists preferences, hotkey slots, and AI prompt profiles.

If hotkeys fail to register, check `GlobalHotkeyManager` in [`Sources/Fluid/Services/GlobalHotkeyManager.swift`](https://github.com/altic-dev/FluidVoice/blob/main/Sources/Fluid/Services/GlobalHotkeyManager.swift). Ensure the app has accessibility permissions (`AXIsProcessTrusted()`) and that the hotkey is registered:

```swift
import Fluid

func verifyHotkey() {
    let manager = GlobalHotkeyManager.shared
    DebugLogger.shared.info("Hotkey is registered: \(manager.isHotkeyRegistered())")
}

```

For corrupted settings, delete specific keys from `~/Library/Preferences/com.altic.FluidVoice.plist` or call `SettingsStore.shared.refreshLoggingEnabled()` after making changes.

## Practical Debugging Workflow

Follow this systematic approach to isolate issues:

1. **Enable logging** using the command line or Settings panel.
2. **Reproduce the issue** while watching the live log for `[ERROR]` or `[DEBUG]` entries.
3. **Add targeted log statements** using `DebugLogger.shared.info()` or `DebugLogger.shared.debug()` in suspicious methods.
4. **Run from Xcode** (`⌘R`) and place breakpoints in `AppDelegate.applicationDidFinishLaunching`, `ContentView.onAppear`, or provider `start()` methods.
5. **Inspect UserDefaults** by dumping all keys when settings appear incorrect:

```swift
for (key, value) in UserDefaults.standard.dictionaryRepresentation() {
    print("\(key) = \(value)")
}

```

6. **Check file logs** at `~/Library/Logs/FluidVoice.log` for crashes occurring before UI initialization.
7. **Export logs** for bug reports using the Debug menu or programmatically:

```swift
let logText = DebugLogger.shared.exportLogs()
try? logText.write(to: URL(fileURLWithPath: "/tmp/FluidVoiceDebug.log"), atomically: true, encoding: .utf8)

```

8. **Verify update checks** by looking for `SimpleUpdater` log entries (`🔎 Manual update check …`) if the update dialog fails to appear.

## Summary

- **Activate debug logging** immediately via `defaults write` or the Settings panel to capture subsystem initialization.
- **Monitor audio flow** by instrumenting `TranscriptionProvider` with `DebugLogger.shared.debug()` calls to verify buffer sizes.
- **Inspect AI prompts** by setting breakpoints on `renderDictationUserMessage` in [`SettingsStore.swift`](https://github.com/altic-dev/FluidVoice/blob/main/SettingsStore.swift).
- **Validate hotkeys** through `GlobalHotkeyManager` and confirm accessibility permissions.
- **Export logs** from the Debug menu or programmatically using `DebugLogger.shared.exportLogs()` for external analysis.

## Frequently Asked Questions

### How do I enable debug logging if FluidVoice crashes on launch?

Use the command line before launching: `defaults write com.altic.FluidVoice EnableDebugLogs -bool true`. Then check the file log at `~/Library/Logs/FluidVoice.log` using Console.app or Terminal, as the in-app UI may not be accessible if the crash occurs during initialization.

### Why is my transcription provider showing "Failed to load model" errors?

Verify the model files exist in `~/Library/Application Support/FluidVoice/Models`. Add `DebugLogger.shared.debug()` calls inside `TranscriptionProvider` to confirm the exact path being accessed, and check that the model format matches what the concrete provider expects (e.g., Parakeet vs. Whisper).

### How can I see the exact prompt sent to the AI post-processing service?

Set a breakpoint on `renderDictationUserMessage` in [`Sources/Fluid/Persistence/SettingsStore.swift`](https://github.com/altic-dev/FluidVoice/blob/main/Sources/Fluid/Persistence/SettingsStore.swift). This method constructs the prompt immediately before sending it to `DictationPostProcessingService`, allowing you to inspect the string content in the Xcode Debug console using `po variableName`.

### What should I check if the global hotkey stops working?

First, verify accessibility permissions are granted using `AXIsProcessTrusted()`. Then check `GlobalHotkeyManager` registration status by calling `GlobalHotkeyManager.shared.isHotkeyRegistered()` and logging the result. Finally, inspect `UserDefaults` for corrupted hotkey bindings using the dictionary dump method described in the debugging workflow.