Hmbown/CodeWhale · error

could not snapshot the Codewhale-owned legacy

Error message

could not snapshot the Codewhale-owned legacy {slot} secret slot before clearing it: {error}; config was not changed

What it means

clear_legacy_antigravity_config migrates away from the legacy Antigravity provider config. Before changing anything it snapshots the existing secret slot via secrets.get(slot); if that read fails, it aborts the whole migration with this message so the config is left untouched. This is a safety checkpoint: never clear a secret you could not first read back.

Solutions

  1. Ensure the OS secret service/keyring is running and unlocked, then retry the migration
  2. Unlock the keychain or grant the CLI access to the slot if access control blocked the read
  3. Fix or reset the secret backend; verify `secrets.get` works for the slot
  4. Skip/defer the legacy migration until the backend is healthy — config remains unchanged
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: verify the slot is readable before triggering the migration
let probe = secrets.get(provider_slot(ProviderKind::Antigravity));
if probe.is_err() { eprintln!("secret backend unavailable; defer legacy cleanup"); }

Try / catch

match clear_legacy_antigravity_config(store, secrets) {
    Err(e) if e.to_string().contains("snapshot") => {
        eprintln!("secret store unreadable — config left unchanged; fix keyring and retry");
    }
    other => other?,
}

Prevention

When it happens

Trigger: `secrets.get(slot)` for the Antigravity slot returns Err — the secret backend (keyring/OS agent) is unavailable, locked, or returns an IO error during the legacy-config cleanup migration.

Common situations: Running the legacy migration on a headless machine without a keyring service, a locked keychain prompting for access, or a corrupted secret store entry.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/5bfd9a2da41ba725. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/lib.rs:2688

        println!("cleared xAI credentials from config, secret store, and owned OAuth storage");
    } else {
        println!("cleared API key for {slot} from config and secret store");
    }
    Ok(())
}

/// Remove only Codewhale-owned state for the retired Antigravity route.
///
/// This deliberately operates on the already-loaded Codewhale config and its
/// own secret slot. It never resolves an external credential path, reads an
/// environment credential, or invokes a Google/Antigravity logout or revoke
/// flow.
fn clear_legacy_antigravity_config(store: &mut ConfigStore, secrets: &Secrets) -> Result<()> {
    let provider = ProviderKind::Antigravity;
    let slot = provider_slot(provider);
    let original_config = store.config.clone();
    let prior_secret = secrets.get(slot).map_err(|error| {
        anyhow!(
            "could not snapshot the Codewhale-owned legacy {slot} secret slot before clearing it: {error}; config was not changed"
        )
    })?;

    store.config.providers.antigravity = Default::default();
    store
        .config
        .fallback_providers
        .retain(|fallback| *fallback != provider);
    if store.config.provider == provider {
        store.config.provider = ProviderKind::default();
        store.config.selected_provider_id = None;
    }

    if let Err(error) = secrets.delete(slot) {
        store.config = original_config;
        return Err(anyhow!(
            "could not clear the Codewhale-owned legacy {slot} secret slot: {error}; config was not changed"

View on GitHub (pinned to 73e0f67d83)