Hmbown/CodeWhale · error
Secret storage snapshot failed for
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
Before mutating the secret store, `set_provider_api_key_unlocked` snapshots the slot's prior value. If the snapshot read itself fails, it rolls back the in-memory config and returns this error rather than proceeding without a known prior state — the API key is never written in plaintext to the config file.
Solutions
- Fix backend availability (unlock keychain / start the secret service) and retry.
- Check read permissions on the secret backend for the current user.
- The config file is unchanged; simply re-run the command once the backend responds.
Defensive patterns
Strategy: try-catch
Try / catch
match set_provider_api_key(provider, key) {
Err(e) if e.to_string().starts_with("Secret storage snapshot failed") => {
eprintln!("Secret backend unreadable; unlock it and retry. Nothing was changed.");
}
other => other?,
} Prevention
- Verify the secret backend answers reads (e.g. list an existing entry) before auth commands
- Keep keychain sessions alive during scripted auth operations
- Check backend permissions for the current user
When it happens
Trigger: Calling `set_provider_api_key` when the secret backend's initial `get(slot)` (snapshot) fails, before any secret write occurs.
Common situations: Keychain/session unavailable, backend permissions denied on read, or secret service crashed between operations.
Related errors
- Secret storage write failed for
- api_key cannot be empty string
- bearer credentials are not an API key
- ; additionally could not verify secret-store rollback for
- ; additionally failed to restore prior secret-store state…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/91bc320a377be65a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/config/src/credentials.rs:120
// 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.",
crate::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.",
crate::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 73e0f67d83)