Hmbown/CodeWhale · error
Secret storage write failed for
Error message
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. What it means
`set_provider_api_key_unlocked` first writes the key to the configured OS secret backend (keychain/credential manager). If that write fails, it restores the original in-memory config and refuses with this error — the API key is never downgraded to plaintext in the config file. The message names the secret slot, the backend error, and the untouched config path.
Solutions
- Unlock or start the OS secret backend (unlock Keychain; start gnome-keyring/keyring daemon; log into the desktop session).
- Retry `set_provider_api_key` after the backend is healthy — the config file was left unchanged.
- Inspect the backend error embedded in the message for access-denied vs unavailable causes.
- If on headless Linux, install/initialize a secret service provider (e.g. `gnome-keyring` or use a file-backed keyring the tool supports).
Example fix
// before (headless Linux, no keyring) $ codewhale auth set openai sk-... Error: Secret storage write failed ... // after $ eval $(gnome-keyring-daemon --start --components=secrets) $ codewhale auth set openai sk-...
Defensive patterns
Strategy: try-catch
Try / catch
match set_provider_api_key(provider, key) {
Err(e) if e.to_string().starts_with("Secret storage write failed") => {
eprintln!("Unlock your OS keychain / start the secret service, then retry. Config file was not modified.");
}
other => other?,
} Prevention
- Ensure the OS keychain/secret service is running and unlocked before auth commands
- On headless Linux, initialize a keyring daemon in your session startup
- Retry rather than trying to store the key in plaintext config
When it happens
Trigger: Calling `set_provider_api_key` when the OS secret store's `set(slot, key)` returns an error (keychain locked, service unavailable, access denied).
Common situations: macOS Keychain locked or denied access, Linux secret service (gnome-keyring/KWallet) not running over SSH, Windows Credential Manager policy restrictions.
Related errors
- Secret storage snapshot 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/894e8621ac0f5482.
Report an issue: GitHub.
Appendix: source
Thrown at crates/config/src/credentials.rs:112
provider: ProviderKind,
api_key: &str,
) -> Result<bool> {
let original_config = store.config.clone();
prepare_provider_api_key_metadata(store, provider);
let slot = provider_slot(provider);
// A readable prior value is required before a secret-store write so a
// later config failure can restore the exact prior state. If the backend
// 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)View on GitHub (pinned to 73e0f67d83)