Hmbown/CodeWhale · critical · anyhow::Error

{error}; additionally could not verify secret-store rollback

Error message

{error}; additionally could not verify secret-store rollback for {slot}: {rollback}

What it means

Compound failure after the secret store accepted the new key: saving the config file failed (store.save()), and the rollback verification read secrets.get(slot) also errored, so codewhale cannot confirm whether the store holds the new or the old value. Both the original save error and the verification uncertainty are reported, and the system may be in a divergent state (new key in store, old config).

Source

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

                    "Secret storage write failed for {slot}: {err}. Refusing to write the API key in plaintext to {}. Fix the configured secret backend and retry; Codewhale did not change that file.",
                    codewhale_config::quote_os_path(store.path())
                ));
            }
        },
        Err(error) => {
            store.config = original_config;
            return Err(anyhow::anyhow!(
                "Secret storage snapshot failed for {slot}: {error}. Refusing to write the API key in plaintext to {}. Fix the configured secret backend and retry; Codewhale did not change that file.",
                codewhale_config::quote_os_path(store.path())
            ));
        }
    };
    if let Err(error) = store.save() {
        store.config = original_config;
        if secret_store_saved {
            let current = secrets
                .get(slot)
                .map_err(|rollback| anyhow::anyhow!(
                    "{error}; additionally could not verify secret-store rollback for {slot}: {rollback}"
                ))?;
            if current.as_deref() == Some(api_key) {
                match prior_secret.expect("snapshot succeeded before secret write") {
                    Some(previous) => secrets.set(slot, &previous),
                    None => secrets.delete(slot),
                }
                .map_err(|rollback| anyhow::anyhow!(
                    "{error}; additionally failed to restore prior secret-store state for {slot}: {rollback}"
                ))?;
            }
        }
        return Err(error);
    }
    codewhale_config::scrub_plaintext_api_keys_from_config_backup(store.path())?;
    Ok(secret_store_saved)
}

View on GitHub (pinned to 8880682c63)

Solutions

  1. Fix the config-file write problem first (permissions, disk space, path)
  2. Manually inspect the slot in the secret backend to learn which key it holds
  3. Rerun the key-set command once writable — it rewrites both sides and converges the state
  4. Preserve the full compound message for diagnostics; it records both failure layers
Defensive patterns

Strategy: fallback

Try / catch

match set_provider_key(&mut store, &mut secrets, key) {
    Ok(_) => {}
    Err(err) if err.to_string().contains("additionally could not verify secret-store rollback") => {
        // Divergent state possible: re-run the same key-set command after fixing the
        // config-write problem; it is idempotent and converges both stores.
        ops::alert_operator(&err);
        repair_config_writability()?;
        set_provider_key(&mut store, &mut secrets, key)?;
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Config file becomes unwritable (read-only $HOME, disk full, permission change) after the key was already written; then the verification read of the slot fails because the backend went away mid-operation.

Common situations: Disk filling up during setup; keyring daemon crashing between write and rollback; permissions revoked mid-flight in hardened environments.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/c8f269318d0a24e1. Report an issue: GitHub.