Budibase/budibase · error · HTTPError

${passwordValidation.error}

Error message

${passwordValidation.error}

What it means

buildUser validates any newly supplied password with validatePassword() and throws the validator's message (HTTPError 400) when it fails the configured password policy (length/complexity rules). The error text is dynamic - `${passwordValidation.error}` - describing exactly which policy rule the password broke.

Source

Thrown at packages/backend-core/src/users/db.ts:139

    account?: Account
  ): Promise<User> {
    let { password, _id } = user

    // don't require a password if the db user doesn't already have one
    if (dbUser && !dbUser.password) {
      opts.requirePassword = false
    }

    let hashedPassword
    if (password && password !== dbUser?.password) {
      if (await UserDB.isPreventPasswordActions(user, account)) {
        throw new HTTPError("Password change is disabled for this user", 400)
      }

      if (!opts.skipPasswordValidation) {
        const passwordValidation = validatePassword(password)
        if (!passwordValidation.valid) {
          throw new HTTPError(passwordValidation.error, 400)
        }
      }

      hashedPassword = opts.hashPassword ? await hash(password) : password
    } else if (dbUser) {
      hashedPassword = dbUser.password
    }

    // passwords are never required if sso is enforced
    const requirePasswords =
      opts.requirePassword && !(await UserDB.features.isSSOEnforced())
    if (!hashedPassword && requirePasswords) {
      throw "Password must be specified."
    }

    _id = _id || dbUtils.generateGlobalUserID()

    const fullUser = {

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Supply a password that satisfies the policy: sufficiently long with mixed character classes
  2. Inspect the error message itself - it names the specific rule that failed
  3. Skip validation only for trusted internal flows by passing opts.skipPasswordValidation = true (rarely appropriate)
  4. Check the tenant's configured password policy and generate conforming passwords programmatically

Example fix

// before
await users.save({ email, password: "abc" })
// after
await users.save({ email, password: "Str0ng!Passw0rd" }) // satisfies policy
Defensive patterns

Strategy: validation

Validate before calling

// validate password client-side before calling save
function isValidPassword(pw: string): boolean {
  return pw.length >= 8 && /[A-Z]/.test(pw) && /[a-z]/.test(pw) && /[0-9]/.test(pw)
}
if (!isValidPassword(password)) throw new Error("Password does not meet policy")

Try / catch

try {
  await users.save(user)
} catch (e: any) {
  if (e?.status === 400) {
    // e.message names the specific policy rule that failed - show it to the user
    showPasswordPolicyHint(e.message)
  } else throw e
}

Prevention

When it happens

Trigger: save/bulkCreate -> buildUser called with a `password` that differs from the stored password and fails validatePassword (too short, no digits/symbols, etc.), unless opts.skipPasswordValidation is true.

Common situations: Creating users via API/scripts with weak default passwords; admin password resets that don't match the tenant policy; automated test fixtures with passwords like "test"; policy tightened between versions so previously valid passwords now fail.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/0b620fad857f1e24. Report an issue: GitHub.