atuinsh/atuin · error
Hub password change failed with status
Error message
Hub password change failed with status {status} What it means
Catch-all in `change_password` (crates/atuin-client/src/auth.rs:420): the Hub returned a non-success status that is neither 401 nor 403, and the body was not a parseable `HubErrorResponse`. Only the HTTP status is reported.
Solutions
- Check the status code: retry with backoff for 429/5xx.
- Check Atuin Hub status for outages.
- Update Atuin to keep client/server error schemas aligned.
- Inspect any proxy between client and Hub that could rewrite responses.
Defensive patterns
Strategy: retry
Validate before calling
// Probe server health before the mutation
let healthy = reqwest::get(format!("{hub}/health"))
.await.map(|r| r.status().is_success()).unwrap_or(false); Try / catch
match client.change_password(cur, new, totp).await {
Err(e) if e.to_string().contains("failed with status") => {
// 429/5xx with unparseable body: retry with exponential backoff
}
other => { /* handle */ }
} Prevention
- Retry with backoff on 429/5xx; never tight-loop the endpoint.
- Check Hub status pages during outages.
- Keep client version in sync with server.
- Audit intermediaries (proxies/LBs) that can replace JSON error bodies.
When it happens
Trigger: PATCH to `/api/v0/account/password` returns e.g. 429 (rate limited), 500/502/503 (server error), or 413, with a body that fails JSON deserialization into `HubErrorResponse`.
Common situations: Hub outage or maintenance window; reverse proxy returning HTML 502 pages; rate limiting from rapid retries; client/server version skew producing unexpected payloads.
Related errors
- Hub account deletion failed with status
- Hub registration failed with status
- model list request failed
- usage request failed
- Hub login failed with status
AI-assisted analysis of atuinsh/atuin@900007c480 (2026-09-19).
Data as JSON: /api/errors/75f502ecaa27ad04.
Report an issue: GitHub.
Appendix: source
Thrown at crates/atuin-client/src/auth.rs:420
Some("2fa_required") => return Ok(MutateResponse::TwoFactorRequired),
Some("invalid_2fa_code") => {
bail!("invalid two-factor code");
}
_ => {
bail!("{}", err.reason);
}
}
}
match status {
StatusCode::UNAUTHORIZED => {
bail!("current password is incorrect");
}
StatusCode::FORBIDDEN => {
bail!("invalid login details");
}
_ => {
bail!("Hub password change failed with status {status}");
}
}
}
async fn delete_account(
&self,
password: &str,
totp_code: Option<&str>,
) -> Result<MutateResponse> {
let hub_token = self.hub_token.as_deref().ok_or_else(|| {
eyre::eyre!("Not logged in to Atuin Hub. Please run 'atuin login' to authenticate.")
})?;
if !hub_token.starts_with("atapi_") {
bail!(
"Your Hub session token is invalid. Please run 'atuin login' to re-authenticate \
with Atuin Hub."
);View on GitHub (pinned to 900007c480)