BigPizzaV3/CodexPlusPlus · error

provider sync task failed

Error message

provider sync task failed: {error}

What it means

This error wraps any failure of the spawned provider-sync background task (spawn_blocking/JoinError or inner sync error) in the Tauri command that synchronizes provider settings. The library re-raises the join/task result as an anyhow error so the Tauri command returns a single failure message to the frontend. It means the async sync worker did not complete successfully, not that the sync logic itself reported a specific domain failure.

Solutions

  1. Inspect the inner `{error}` text in the message to find the root cause (panic vs sync error)
  2. Re-run the provider sync from the UI; transient panics/races often clear on retry
  3. Check config.toml and provider profile settings for invalid values that make the sync task panic
  4. If it persists, add logging/Backtrace on the spawned task to capture the panic site in commands.rs

Example fix

// before
let result = tokio::task::spawn_blocking(move || sync_provider(progress)).await
    .map_err(|error| anyhow::anyhow!("provider sync task failed: {error}"));
// after
let result = match tokio::task::spawn_blocking(move || sync_provider(progress)).await {
    Ok(inner) => inner, // keep domain error separate from JoinError
    Err(join_err) if join_err.is_panic() => {
        tracing::error!("provider sync panicked: {join_err}");
        return Err(anyhow::anyhow!("provider sync task failed: {join_err}"));
    }
    Err(join_err) => return Err(anyhow::anyhow!("provider sync task cancelled: {join_err}")),
};
Defensive patterns

Strategy: try-catch

Try / catch

// Rust
match sync_providers_command(...).await {
    Ok(sync) => apply(sync),
    Err(e) if e.to_string().contains("provider sync task failed") => {
        log::error!("sync task: {e:#}");
        // surface retry UI
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: The spawned tokio task that runs the provider sync (receiving progress callbacks) panics, is cancelled, or returns Err; `.await` on the JoinHandle maps that via `anyhow::anyhow!("provider sync task failed: {error}")`.

Common situations: Task panic inside sync code (e.g. poisoned lock, unwrap on missing config), runtime shutdown while sync is in flight, or an underlying sync error (network/config) bubbled up through the task.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19). Data as JSON: /api/errors/bd8f01069a6f9fcb. Report an issue: GitHub.

Appendix: source

Thrown at apps/codex-plus-manager/src-tauri/src/commands.rs:3331

    let target_for_settings = target_provider.clone();
    let home = codex_plus_core::relay_config::default_codex_home_dir();
    prepare_codex_app_state_before_provider_switch(&home, "manager.sync_providers_now.before");
    let progress_window = window.clone();
    let result = tauri::async_runtime::spawn_blocking(move || {
        codex_plus_data::run_provider_sync_with_target_and_progress(
            None,
            target_provider.as_deref(),
            |progress| {
                let _ = progress_window.emit_to(
                    progress_window.label(),
                    PROVIDER_SYNC_PROGRESS_EVENT,
                    progress,
                );
            },
        )
    })
    .await
    .map_err(|error| anyhow::anyhow!("provider sync task failed: {error}"));
    match result {
        Ok(sync) => {
            if is_success_sync_status(&sync.status) {
                persist_provider_sync_selection(
                    target_for_settings
                        .as_deref()
                        .unwrap_or(&sync.target_provider),
                );
                finish_codex_app_state_after_provider_switch(
                    &home,
                    "manager.sync_providers_now.after",
                );
            }
            let _ = codex_plus_core::diagnostic_log::append_diagnostic_log(
                "manager.provider_sync.completed",
                json!({
                    "status": sync.status.clone(),
                    "changedSessionFiles": sync.changed_session_files,

View on GitHub (pinned to b1ed92e5e4)