BigPizzaV3/CodexPlusPlus · error · anyhow::Error

provider sync did not complete

Error message

provider sync did not complete ({status:?}): {message}

What it means

require_completed_provider_sync validates that a provider sync reached the terminal Synced state before the launcher proceeds. Any other ProviderSyncStatus variant (e.g. Pending, Failed, InProgress) causes an anyhow::bail! with the stored status and message, aborting the calling operation. It exists to prevent the launcher from running against an incompletely synchronized provider.

Solutions

  1. Read the embedded `message` in the error — it carries the reason the earlier sync failed — and fix that root cause first.
  2. Re-run the provider sync step so the status transitions to Synced before launching.
  3. Inspect the provider sync record in the codex-plus data store (db_path) to confirm the current status and reset/retry it.
  4. Check connectivity/upstream provider availability if the stored message indicates a network or API failure.
  5. If this occurs in tests, ensure the fixture actually completes the sync or asserts the bail for the intended non-Synced variant.

Example fix

// before
require_completed_provider_sync(&status, &message)?;
// after
if status != codex_plus_data::ProviderSyncStatus::Synced {
    run_provider_sync(&mut service)?; // retry the sync before bailing
}
require_completed_provider_sync(&status, &message)?;
Defensive patterns

Strategy: validation

Validate before calling

// check before invoking launcher paths that require sync
let status = service.load_provider_sync_status()?;
anyhow::ensure!(
    status == codex_plus_data::ProviderSyncStatus::Synced,
    "run provider sync first (current: {status:?})"
);

Type guard

fn is_synced(status: &codex_plus_data::ProviderSyncStatus) -> bool {
    matches!(status, codex_plus_data::ProviderSyncStatus::Synced)
}

Try / catch

// propagate with context instead of losing the stored message
require_completed_provider_sync(&status, &message)
    .context("launcher preflight: provider sync incomplete")?;

Prevention

When it happens

Trigger: run_provider_sync (or the test launcher_accepts_only_a_completed_provider_sync) loads a codex_plus_data::ProviderSyncStatus from the data store and passes it to require_completed_provider_sync; the function bails when `*status != ProviderSyncStatus::Synced`, embedding the Debug status and stored message in the error. Raised at apps/codex-plus-launcher/src/main.rs:635.

Common situations: A previous sync crashed or was interrupted leaving status Pending/Failed; the data store was created but sync never ran; a prior sync recorded an error message (network, upstream API failure) that now surfaces here; tests injecting a non-Synced status on purpose.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at apps/codex-plus-launcher/src/main.rs:635

    }

    async fn shutdown_helper(&self, helper_port: u16) {
        self.core.shutdown_helper(helper_port).await;
    }

    async fn terminate_codex(&self, launch: &codex_plus_core::launcher::CodexLaunch) {
        self.core.terminate_codex(launch).await;
    }
}

fn require_completed_provider_sync(
    status: &codex_plus_data::ProviderSyncStatus,
    message: &str,
) -> anyhow::Result<()> {
    if *status == codex_plus_data::ProviderSyncStatus::Synced {
        return Ok(());
    }
    anyhow::bail!("provider sync did not complete ({status:?}): {message}")
}

#[derive(Debug, Clone)]
struct LauncherDataService {
    db_path: PathBuf,
    backup_dir: PathBuf,
}

impl Default for LauncherDataService {
    fn default() -> Self {
        Self {
            db_path: default_codex_db_path(),
            backup_dir: codex_plus_core::paths::default_app_state_dir().join("backups"),
        }
    }
}

#[async_trait::async_trait]

View on GitHub (pinned to b1ed92e5e4)