atuinsh/atuin · error

invalid login details

Error message

invalid login details

What it means

This bail fires when the `PATCH account/password` request returns HTTP 403. The client interprets 403 as 'the credentials you presented are not authorized for this account operation' — the login details (token/session vs. account) don't match. Unlike 401 (bad current password), 403 means authenticated but forbidden.

Solutions

  1. Confirm the logged-in account matches the account you intend to change (`atuin status` / stored session identity)
  2. Log in again to the correct account, then retry the password change
  3. Check whether the account is managed/linked and disallows direct password changes on this server
  4. Verify `sync_address` points at the server that issued your current session

Example fix

null
Defensive patterns

Strategy: try-catch

Type guard

fn is_forbidden_change(err: &Report) -> bool {
    err.to_string() == "invalid login details"
}

Try / catch

match auth_client.change_password(current, new, totp).await {
    Ok(MutateResponse::Success) => println!("password updated"),
    Err(e) if e.to_string() == "invalid login details" => {
        eprintln!("session not authorized for this account; re-login as the correct user");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `change_password` with a session token that belongs to a different account than the password being changed, or the server explicitly forbids the operation for this authenticated identity.

Common situations: Mixing sessions after switching accounts on one machine; a server policy blocks password change for this account (e.g. managed/OAuth-linked accounts); stale config pointing at a different sync server than the one the session was issued by.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of atuinsh/atuin@900007c480 (2026-09-19). Data as JSON: /api/errors/36f24d84bd4b94f2. Report an issue: GitHub.

Appendix: source

Thrown at crates/atuin-client/src/auth.rs:208

        let client = self.authenticated_client()?;
        let url = self.address.append_path("account/password")?;

        let resp = client
            .patch(url)
            .json(&ChangePasswordRequest {
                current_password: current_password.to_string(),
                new_password: new_password.to_string(),
            })
            .send()
            .await?;

        match resp.status().as_u16() {
            200 => Ok(MutateResponse::Success),
            401 => {
                bail!("current password is incorrect");
            }
            403 => {
                bail!("invalid login details");
            }
            _ => {
                bail!("unknown error");
            }
        }
    }

    async fn delete_account(
        &self,
        password: &str,
        _totp_code: Option<&str>,
    ) -> Result<MutateResponse> {
        let client = self.authenticated_client()?;
        let url = self.address.append(["account"])?;

        let resp =
            client.delete(url).json(&serde_json::json!({ "password": password })).send().await?;

View on GitHub (pinned to 900007c480)