{"record":{"id":"894e8621ac0f5482","repo":"Hmbown/CodeWhale","slug":"secret-storage-write-failed-for-slot-err-refusing-to-write","errorCode":null,"errorMessage":"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.","messagePattern":"Secret storage write failed for (.+?): (.+?)\\. Refusing to write the API key in plaintext to (.+?)\\. Fix the configured secret backend and retry; Codewhale did not change that file\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/config/src/credentials.rs","lineNumber":112,"sourceCode":"    provider: ProviderKind,\n    api_key: &str,\n) -> Result<bool> {\n    let original_config = store.config.clone();\n    prepare_provider_api_key_metadata(store, provider);\n    let slot = provider_slot(provider);\n    // A readable prior value is required before a secret-store write so a\n    // later config failure can restore the exact prior state. If the backend\n    // cannot provide that snapshot, fail before changing the config file.\n    let prior_secret = secrets.get(slot);\n    let secret_store_saved = match prior_secret.as_ref().map_err(|error| error.to_string()) {\n        Ok(_) => match secrets.set(slot, api_key) {\n            Ok(()) => {\n                clear_provider_api_key_from_config(store, provider);\n                true\n            }\n            Err(err) => {\n                store.config = original_config;\n                return Err(anyhow::anyhow!(\n                    \"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.\",\n                    crate::quote_os_path(store.path())\n                ));\n            }\n        },\n        Err(error) => {\n            store.config = original_config;\n            return Err(anyhow::anyhow!(\n                \"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.\",\n                crate::quote_os_path(store.path())\n            ));\n        }\n    };\n    if let Err(error) = store.save() {\n        store.config = original_config;\n        if secret_store_saved {\n            let current = secrets\n                .get(slot)","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/config/src/credentials.rs#L94-L130","documentation":"`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.","triggerScenarios":"Calling `set_provider_api_key` when the OS secret store's `set(slot, key)` returns an error (keychain locked, service unavailable, access denied).","commonSituations":"macOS Keychain locked or denied access, Linux secret service (gnome-keyring/KWallet) not running over SSH, Windows Credential Manager policy restrictions.","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)."],"exampleFix":"// before (headless Linux, no keyring)\n$ codewhale auth set openai sk-...\nError: Secret storage write failed ...\n// after\n$ eval $(gnome-keyring-daemon --start --components=secrets)\n$ codewhale auth set openai sk-...","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match set_provider_api_key(provider, key) {\n    Err(e) if e.to_string().starts_with(\"Secret storage write failed\") => {\n        eprintln!(\"Unlock your OS keychain / start the secret service, then retry. Config file was not modified.\");\n    }\n    other => other?,\n}","preventionTips":["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"],"tags":["secret-storage","keychain","api-key","credentials"],"backgroundTag":"secret-storage-write-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}