Budibase/budibase · error · HTTPError

IMAP password is required when connection details change

Error message

IMAP password is required when connection details change

What it means

When testing with a masked (saved) password, the supplied connection details (host, port, username, secure) must exactly match what is stored on the automation's trigger, otherwise the saved password would be used against a different server. If any detail differs, HTTP 400 is thrown.

Source

Thrown at packages/server/src/api/controllers/automation.ts:265

  const trigger = automation.definition.trigger
  if (!trigger) {
    throw new HTTPError("No trigger found for automation", 400)
  }
  if (!isEmailTrigger(trigger)) {
    throw new HTTPError("Automation trigger is not an email trigger", 400)
  }
  if (!trigger.inputs.password) {
    throw new HTTPError("IMAP password is required", 400)
  }

  const stored = trigger.inputs
  const connectionMatches =
    emailInputs.host === stored.host &&
    emailInputs.port === stored.port &&
    emailInputs.username === stored.username &&
    emailInputs.secure === stored.secure
  if (!connectionMatches) {
    throw new HTTPError(
      "IMAP password is required when connection details change",
      400
    )
  }

  return {
    ...emailInputs,
    password: stored.password,
  }
}

export async function testEmailConnection(
  ctx: UserCtx<TestEmailConnectionRequest, TestEmailConnectionResponse>
) {
  try {
    await testConnection(await hydrateEmailConnectionPassword(ctx.request.body))
    ctx.body = { valid: true }
  } catch (err: any) {

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Revert the changed host/port/username/secure fields to match the saved automation, or
  2. Enter the real plaintext password alongside the new connection details so hydration isn't needed
  3. Update the saved automation's trigger inputs first, then test with the masked password

Example fix

// before
test({ automationId, emailInputs: { host: 'new.mail.com', port: 993, username: 'user', secure: true, password: '####' } })
// after
test({ automationId, emailInputs: { host: 'new.mail.com', port: 993, username: 'user', secure: true, password: 'real-password' } })
Defensive patterns

Strategy: validation

Validate before calling

const stored = automation.definition?.trigger?.inputs
if (isMaskedPassword(emailInputs.password) && stored &&
  (emailInputs.host !== stored.host || emailInputs.port !== stored.port ||
   emailInputs.username !== stored.username || emailInputs.secure !== stored.secure)) {
  throw new Error('Connection details changed; supply the real password')
}

Try / catch

try {
  await testEmailConnection({ emailInputs, automationId })
} catch (e) {
  if (e.status === 400 && e.message.includes('connection details change')) {
    // require the user to enter the real password for the new settings
  }
}

Prevention

When it happens

Trigger: testEmailConnection with a masked password where host, port, username, or secure differs from the values saved on the automation's email trigger inputs.

Common situations: User changed host/port/username in the test form but left the masked password field; migrating the automation to a new mail server; copy-pasting connection settings from another source.

Related errors


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