moghtech/komodo · error · anyhow::Error
Service Users cannot add additional login methods
Error message
Service Users cannot add additional login methods
What it means
set_user_hashed_password inspects the user's UserConfig before building the update document: if the user is a Service user (machine account), no password login method may be attached to it, so the update is rejected with this error. It is a business-rule guard protecting the invariant that Service accounts authenticate via other means, not passwords.
Solutions
- Only call password updates for users with UserConfig::Local
- Filter service users out in admin reset flows (match user.config before calling)
- If the account should have a password, it was mis-provisioned — recreate it as a Local user
- Use the service account's intended credential mechanism instead of a password
Example fix
// before
for user in users { db.set_user_password(&user, tmp_pw).await?; }
// after
for user in users {
if matches!(user.config, UserConfig::Local { .. }) {
db.set_user_password(&user, tmp_pw).await?;
}
} Defensive patterns
Strategy: type-guard
Validate before calling
fn can_set_password(user: &User) -> bool {
matches!(user.config, UserConfig::Local { .. })
} Type guard
fn is_local_user(user: &User) -> bool {
matches!(user.config, UserConfig::Local { .. })
} Try / catch
match db.set_user_password(&user, &pw).await {
Err(e) if e.to_string().contains("Service Users cannot") => {
log::info!("skipped password reset for service account {}", user.id);
Ok(())
}
other => other,
} Prevention
- Check user.config before any password-related call
- Exclude UserConfig::Service accounts from password-reset UIs and bulk scripts
- Track service accounts separately from human accounts in admin tooling
When it happens
Trigger: Calling set_user_hashed_password (directly or via set_user_password) on a User whose config is UserConfig::Service.
Common situations: Admin password-reset UI iterating over all users including service accounts; scripts that reset passwords for automation users; mixing up a service account's ID with a human user's ID.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
AI-assisted analysis of moghtech/komodo@780ac68b99 (2026-09-08).
Data as JSON: /api/errors/bd40b2a486c089f3.
Report an issue: GitHub.
Appendix: source
Thrown at lib/database/src/lib.rs:138
password: &str,
) -> anyhow::Result<()> {
if password.is_empty() {
return Err(anyhow!("Password cannot be empty."));
}
let hashed_password =
hash_password(password).context("Failed to hash password")?;
self.set_user_hashed_password(user, hashed_password).await
}
/// Updates a user's password using a DB call.
pub async fn set_user_hashed_password(
&self,
user: &User,
hashed_password: String,
) -> anyhow::Result<()> {
let update = match user.config {
UserConfig::Service { .. } => {
return Err(anyhow!(
"Service Users cannot add additional login methods"
));
}
// Update a primary 'Local' user's password directly.
UserConfig::Local { .. } => {
doc! {
"$set": {
"config.data.password": hashed_password
}
}
}
// Update User with Local password as an entry in 'additional_logins'
_ => {
let bson = to_bson(&UserConfig::Local {
password: hashed_password,
})
.context("Failed to serialize login method to bson")?;
doc! {View on GitHub (pinned to 780ac68b99)