Zackriya-Solutions/meetily · error · anyhow::Error

Failed to serialize preferences: {}

Error message

Failed to serialize preferences: {}

What it means

serde_json::to_value(&preferences) failed while converting RecordingPreferences into a JSON value before writing it to the store. With derive-based Serialize this path is nearly unreachable; it fires only when a field's type or a custom Serialize impl actively produces an error (for example a map with non-string keys, or a manual impl returning Err).

Source

Thrown at frontend/src-tauri/src/audio/recording_preferences.rs:153

}

/// Save recording preferences to store
pub async fn save_recording_preferences<R: Runtime>(
    app: &AppHandle<R>,
    preferences: &RecordingPreferences,
) -> Result<()> {
    info!("Saving recording preferences: save_folder={:?}, auto_save={}, format={}, mic={:?}, system={:?}",
          preferences.save_folder, preferences.auto_save, preferences.file_format,
          preferences.preferred_mic_device, preferences.preferred_system_device);

    // Get or create store
    let store = app
        .store("recording_preferences.json")
        .map_err(|e| anyhow::anyhow!("Failed to access store: {}", e))?;

    // Serialize preferences to JSON value
    let prefs_value = serde_json::to_value(preferences)
        .map_err(|e| anyhow::anyhow!("Failed to serialize preferences: {}", e))?;

    // Save to store
    store.set("preferences", prefs_value);

    // Persist to disk
    store
        .save()
        .map_err(|e| anyhow::anyhow!("Failed to save store to disk: {}", e))?;

    info!("Successfully persisted recording preferences to disk");

    // Save backend preference to global config
    #[cfg(target_os = "macos")]
    if let Some(backend_str) = &preferences.system_audio_backend {
        if let Some(backend) = AudioCaptureBackend::from_string(backend_str) {
            info!("Setting audio capture backend to: {:?}", backend);
            crate::audio::capture::set_current_backend(backend);
        }

View on GitHub (pinned to 0281737d87)

Solutions

  1. Read the serde error message - it names the offending field
  2. Ensure every field of RecordingPreferences derives or implements Serialize
  3. Replace HashMap<NonStringKey, _> with string keys or serialize keys explicitly
Defensive patterns

Strategy: validation

Validate before calling

// Startup round-trip: fail fast in debug builds if the prefs struct stops serializing
#[cfg(debug_assertions)]
{
    let probe = serde_json::to_value(RecordingPreferences::default())
        .expect("RecordingPreferences must serialize");
    let _back: RecordingPreferences = serde_json::from_value(probe)
        .expect("RecordingPreferences must round-trip");
}

Prevention

When it happens

Trigger: A newly added RecordingPreferences field whose type cannot serialize to JSON (HashMap with non-string key types, a hand-written Serialize with failure branches); a field type changed to one that no longer implements Serialize correctly.

Common situations: Struct evolution across app versions; copying in a custom type whose Serialize impl has error paths; Path types containing non-UTF-8 data passed through custom serialization.

Related errors


AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16). Data as JSON: /api/errors/74fc3d98b5621e87. Report an issue: GitHub.