tinyhumansai/openhuman · error · anyhow::Error
Keychain set failed for profile {}: {e} | detail={}
Error message
Keychain set failed for profile {}: {e} | detail={} What it means
Storing an auth profile's secret JSON into the OS keychain failed for that profile id. The keychain write (entry keyed `KEYCHAIN_AUTH_PREFIX + profile_id`) errored — common causes are keychain locked/unavailable, access denied, or on systems without a keychain backend an unwritable filesystem fallback. `{e}` and its diagnostic detail identify the backend cause.
Source
Thrown at src/openhuman/security/credentials/profiles.rs:325
format!("{KEYCHAIN_AUTH_PREFIX}{profile_id}")
}
/// Store auth secrets for a profile in the OS keychain.
///
/// The secrets are serialized as a compact JSON object so a single
/// keychain entry holds all token fields for the profile.
fn keychain_store_secrets(&self, profile: &AuthProfile) -> anyhow::Result<()> {
let key = self.keychain_key_for_profile(&profile.id);
let secrets = serde_json::json!({
"token": profile.token,
"access_token": profile.token_set.as_ref().map(|ts| &ts.access_token),
"refresh_token": profile.token_set.as_ref().and_then(|ts| ts.refresh_token.as_deref()),
"id_token": profile.token_set.as_ref().and_then(|ts| ts.id_token.as_deref()),
});
let payload = serde_json::to_string(&secrets)
.context("Failed to serialize auth secrets for keychain")?;
crate::openhuman::security::keyring::set(&self.user_id, &key, &payload).map_err(|e| {
anyhow::anyhow!(
"Keychain set failed for profile {}: {e} | detail={}",
profile.id,
e.diagnostic()
)
})?;
log::debug!(
"[auth] keychain_store_secrets stored profile_id={} user_id={}",
profile.id,
self.user_id
);
Ok(())
}
/// Load auth secrets for a profile from the OS keychain.
///
/// Returns `None` if no keychain entry exists for the profile.
fn keychain_load_secrets(&self, profile_id: &str) -> anyhow::Result<Option<KeychainSecrets>> {
let key = self.keychain_key_for_profile(profile_id);View on GitHub (pinned to 7491200858)
Solutions
- Check the keychain/keyring backend is available and unlocked
- Verify filesystem permissions for file-backed keyring fallbacks
- Read `{e}` diagnostic detail for the backend-specific cause
- Retry after unlocking the keychain
- Never log the secret payload while diagnosing
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at src/openhuman/security/credentials/profiles.rs:325 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/fbac3bab2e4e98c1.
Report an issue: GitHub.