Hmbown/CodeWhale · critical

; additionally could not verify rollback of the…

Error message

{error}; additionally could not verify rollback of the Codewhale-owned legacy {slot} secret slot: {rollback}

What it means

If store.save() fails after the legacy Antigravity slot was cleared, the code rolls back the in-memory config and tries to restore the previously snapshotted secret. When verifying the current secret (secrets.get) itself fails during that rollback, both the original save error and the rollback-verification error are combined into this compound message — a double failure during transactional cleanup.

Solutions

  1. Fix the secret backend first (restart/unlock the keyring) so rollback verification can proceed
  2. Fix the underlying config save failure (disk space, file permissions on the config path)
  3. Manually restore the snapshotted secret into the slot, then re-run the migration
  4. Inspect both embedded errors ({error} and {rollback}) in the message to determine which subsystem to repair
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight both subsystems before migration
if secrets.get(slot).is_err() { eprintln!("secret backend unhealthy; abort migration"); }
if store.save_probe().is_err() { eprintln!("config path not writable; abort migration"); }

Try / catch

match result {
    Err(e) if e.to_string().contains("additionally could not verify rollback") => {
        // both save and rollback-verify failed: restore from backup manually
        eprintln!("double failure during legacy cleanup; restore secret from snapshot manually");
    }
    other => other?,
}

Prevention

When it happens

Trigger: store.save() fails AND the subsequent secrets.get(slot) used to verify rollback state also returns Err — typically because the secret backend became unavailable mid-migration.

Common situations: Disk-full or permissions failure on the config save combined with a keyring service crash or lock, e.g. during system shutdown or an automated migration on a flaky headless host.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

        .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"
        ));
    }

    if let Err(error) = store.save() {
        store.config = original_config;
        if let Some(previous) = prior_secret {
            let current = secrets.get(slot).map_err(|rollback| {
                anyhow!(
                    "{error}; additionally could not verify rollback of the Codewhale-owned legacy {slot} secret slot: {rollback}"
                )
            })?;
            match current {
                None => secrets.set(slot, &previous).map_err(|rollback| {
                    anyhow!(
                        "{error}; additionally failed to restore the Codewhale-owned legacy {slot} secret slot: {rollback}"
                    )
                })?,
                Some(current) if current == previous => {}
                Some(_) => {
                    return Err(anyhow!(
                        "{error}; additionally the Codewhale-owned legacy {slot} secret slot changed concurrently and was not overwritten during rollback"
                    ));
                }
            }
        }
        return Err(error);

View on GitHub (pinned to 73e0f67d83)