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

  1. Check the keychain/keyring backend is available and unlocked
  2. Verify filesystem permissions for file-backed keyring fallbacks
  3. Read `{e}` diagnostic detail for the backend-specific cause
  4. Retry after unlocking the keychain
  5. 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.