{"record":{"id":"b8f575fb57bcea45","repo":"Budibase/budibase","slug":"imap-password-is-required","errorCode":null,"errorMessage":"IMAP password is required","messagePattern":"IMAP password is required","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/automation.ts","lineNumber":255,"sourceCode":"    )\n  }\n\n  const automation = await context\n    .getWorkspaceDB()\n    .tryGet<Automation>(automationId)\n  if (!automation) {\n    throw new HTTPError(\"Automation not found\", 404)\n  }\n\n  const trigger = automation.definition.trigger\n  if (!trigger) {\n    throw new HTTPError(\"No trigger found for automation\", 400)\n  }\n  if (!isEmailTrigger(trigger)) {\n    throw new HTTPError(\"Automation trigger is not an email trigger\", 400)\n  }\n  if (!trigger.inputs.password) {\n    throw new HTTPError(\"IMAP password is required\", 400)\n  }\n\n  const stored = trigger.inputs\n  const connectionMatches =\n    emailInputs.host === stored.host &&\n    emailInputs.port === stored.port &&\n    emailInputs.username === stored.username &&\n    emailInputs.secure === stored.secure\n  if (!connectionMatches) {\n    throw new HTTPError(\n      \"IMAP password is required when connection details change\",\n      400\n    )\n  }\n\n  return {\n    ...emailInputs,\n    password: stored.password,","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/automation.ts#L237-L273","documentation":"The email trigger exists and is the right type, but its saved inputs contain no password field. There is nothing stored to hydrate the masked password from, so testing with a masked password is impossible and HTTP 400 is thrown.","triggerScenarios":"The saved email trigger was configured without a password (empty field at save time) or the password was stripped/cleared, and the caller now sends a masked password for testEmailConnection.","commonSituations":"Older automations saved before password capture; password cleared during an edit; imported automations with sanitized inputs.","solutions":["Open the automation's email trigger and re-enter the IMAP password, then save","Send the plaintext password in the test request instead of the masked value","Re-create the trigger inputs if the definition is corrupt"],"exampleFix":"// before\n// trigger.inputs saved without password\n// after\nawait api.saveAutomation({ ...automation, definition: { trigger: { ...trigger, inputs: { ...trigger.inputs, password: 'real-password' } } } })","handlingStrategy":"validation","validationCode":"const trigger = automation.definition?.trigger\nif (trigger && !trigger.inputs?.password) throw new Error('Saved email trigger has no stored password; re-enter it before testing with a masked password')","typeGuard":"function hasStoredPassword(t: { inputs?: { password?: string } }): t is { inputs: { password: string } } {\n  return typeof t.inputs?.password === 'string' && t.inputs.password.length > 0\n}","tryCatchPattern":"try {\n  await testEmailConnection({ emailInputs, automationId })\n} catch (e) {\n  if (e.status === 400 && e.message.includes('IMAP password is required')) {\n    // prompt user to re-enter the IMAP password on the trigger\n  }\n}","preventionTips":["Always save a password with email trigger inputs","Re-enter credentials after importing or migrating automations","Validate trigger inputs (password present) before save"],"tags":["automation","imap","password","missing-data"],"backgroundTag":"missing-required-parameter","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}