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

Failed to serialize onboarding status: {}

Error message

Failed to serialize onboarding status: {}

What it means

serde_json::to_value(&status) failed while serializing OnboardingStatus before writing it to the store. With #[derive(Serialize)] this almost never fails; the error means some field's Serialize implementation errored - a custom impl, a map with non-string keys, or a type whose serialization can fail at runtime.

Source

Thrown at frontend/src-tauri/src/onboarding.rs:97

/// Save onboarding status to store
pub async fn save_onboarding_status<R: Runtime>(
    app: &AppHandle<R>,
    status: &OnboardingStatus,
) -> Result<()> {
    info!("Saving onboarding status: step={}, completed={}",
          status.current_step, status.completed);

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

    // Update last_updated timestamp
    let mut status = status.clone();
    status.last_updated = chrono::Utc::now().to_rfc3339();

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

    // Save to store
    store.set("status", status_value);

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

    info!("Successfully persisted onboarding status to disk");
    Ok(())
}

/// Reset onboarding status (delete from store)
pub async fn reset_onboarding_status<R: Runtime>(
    app: &AppHandle<R>,
) -> Result<()> {
    info!("Resetting onboarding status");

View on GitHub (pinned to 0281737d87)

Solutions

  1. Keep OnboardingStatus fields derive(Serialize)-only and avoid custom fallible impls
  2. Add a unit test that round-trips OnboardingStatus through serde_json to catch regressions
  3. If a custom impl is required, make it infallible or map the error with field context
Defensive patterns

Strategy: try-catch

Validate before calling

// Cheap pre-write check: the status must round-trip before it can be persisted
fn serializable(status: &OnboardingStatus) -> bool {
    serde_json::to_value(status).is_ok()
}

Try / catch

let status_value = serde_json::to_value(&status)
    .map_err(|e| anyhow!("OnboardingStatus serialization failed: {e} - check recently added fields for custom Serialize impls"))?;

Prevention

When it happens

Trigger: A field added to OnboardingStatus whose Serialize impl can return an error (custom trait impls, non-string-keyed maps); changing current_step/last_updated types without updating derives.

Common situations: Refactors that introduce custom Serialize impls; persisted types gaining runtime-constrained fields.

Related errors


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