Hmbown/CodeWhale · error · anyhow::Error

Secret storage snapshot failed for {slot}: {error}. Refusing

Error message

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.

What it means

Same migration path failing one step earlier: the pre-write snapshot read secrets.get(slot) errored. Because a snapshot of prior state is required to roll back a later failure, codewhale aborts before touching either the secret store or the config file and reports the read error.

Source

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

    // cannot provide that snapshot, fail before changing the config file.
    let prior_secret = secrets.get(slot);
    let secret_store_saved = match prior_secret.as_ref().map_err(|error| error.to_string()) {
        Ok(_) => match secrets.set(slot, api_key) {
            Ok(()) => {
                clear_provider_api_key_from_config(store, provider);
                true
            }
            Err(err) => {
                store.config = original_config;
                return Err(anyhow::anyhow!(
                    "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),
                }

View on GitHub (pinned to 8880682c63)

Solutions

  1. Fix/unlock the secret backend so reads succeed
  2. Inspect and, if corrupted, delete the provider's slot via backend tooling, then retry
  3. Check backend daemon logs (secret-service, keyring) for the underlying read error
  4. Retry the key-set command; nothing was modified
Defensive patterns

Strategy: validation

Validate before calling

// Verify both read and write on the exact slot before starting migration:
fn slot_accessible(secrets: &codewhale_secrets::Secrets, slot: &str) -> bool {
    secrets.get(slot).is_ok() // snapshot read must succeed first
}

Prevention

When it happens

Trigger: secrets.get fails while setting a provider API key: backend read errors, permission changes on the slot, or a corrupted existing entry in the credential store.

Common situations: Same backend availability issues as the write failure, plus damaged slot entries from previous crashes or manual keyring edits.

Related errors


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