{"record":{"id":"16b76e29d42d9bbb","repo":"flowable/flowable-engine","slug":"failed-to-add-body-part","errorCode":null,"errorMessage":"Failed to add body part","messagePattern":"Failed to add body part","errorType":"exception","errorClass":"FlowableMailException","httpStatus":null,"severity":"error","filePath":"modules/flowable-mail/src/main/java/org/flowable/mail/common/impl/jakarta/mail/JakartaMailFlowableMailClient.java","lineNumber":293,"sourceCode":"    protected MimeMultipart createMultiPartContent(String text, String html, String charset, Collection<DataSource> attachments) throws MessagingException {\n        boolean attachmentsExists = attachments != null && !attachments.isEmpty();\n\n        MimeMultipart rootContainer = new MimeMultipart();\n        MimeMultipart bodyContainer = rootContainer;\n\n        rootContainer.setSubType(\"mixed\");\n\n        if (StringUtils.isNotEmpty(text) && StringUtils.isNotEmpty(html)) {\n            if (attachmentsExists) {\n                // If both HTML and TEXT bodies are provided, create an alternative\n                // container and add it to the root container\n                bodyContainer = new MimeMultipart(\"alternative\");\n                MimeBodyPart bodyPart = new MimeBodyPart();\n                try {\n                    bodyPart.setContent(bodyContainer);\n                    rootContainer.addBodyPart(bodyPart);\n                } catch (MessagingException ex) {\n                    throw new FlowableMailException(\"Failed to add body part\", ex);\n                }\n            } else {\n                // no attachments present, change the mimetype\n                // of the root container (= body container)\n                rootContainer.setSubType(\"alternative\");\n            }\n        }\n\n        if (StringUtils.isNotEmpty(html)) {\n            MimeBodyPart msgHtml = new MimeBodyPart();\n            bodyContainer.addBodyPart(msgHtml, 0);\n            msgHtml.setText(html, charset, \"html\");\n\n            String contentType = msgHtml.getContentType();\n            if (contentType == null || !contentType.equals(CONTENT_TYPE_TEXT_HTML)) {\n                if (StringUtils.isNotEmpty(charset)) {\n                    msgHtml.setContent(html, CONTENT_TYPE_TEXT_HTML + \"; charset=\" + charset);\n                } else {","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-mail/src/main/java/org/flowable/mail/common/impl/jakarta/mail/JakartaMailFlowableMailClient.java#L275-L311","documentation":"Inside createMultiPartContent(), when attachments exist, an 'alternative' multipart holding the text/html body must be wrapped in a MimeBodyPart and added to the root multipart. If bodyPart.setContent(...) or rootContainer.addBodyPart(...) throws MessagingException, it is wrapped as FlowableMailException \"Failed to add body part\".","triggerScenarios":"Sending an email with BOTH a text/html body AND attachments, where attaching the nested body container to the root multipart fails with MessagingException.","commonSituations":"Jakarta Mail provider-level failures when nesting multiparts; corrupted session/properties state; rarely hit — usually points to a broken mail provider setup or a header write failure on the composed part.","solutions":["Read the nested MessagingException 'ex' cause for the actual failure reason","Verify the jakarta.mail (Angus Mail) implementation is up to date and consistent","Reproduce with a simple text+one-attachment email to isolate the failing part","If custom mail properties are set (mail.mime.*), test removing them"],"exampleFix":"// before: conflicting custom MIME properties\nproperties.put(\"mail.mime.encodeparameters\", \"false\");\nproperties.put(\"mail.mime.decodeparameters\", \"true\");\n// after: remove conflicting overrides and rely on defaults\n// (no mail.mime.* overrides)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    mailClient.send(mailMessage);\n} catch (FlowableMailException e) {\n    if (e.getMessage().contains(\"Failed to add body part\")) {\n        log.error(\"Nested multipart assembly failed; review mail.mime.* overrides and provider\", e.getCause());\n    }\n}","preventionTips":["Do not override mail.mime.* session properties unless necessary","Keep the Jakarta Mail provider (Angus Mail) up to date","Test body+attachment combinations after any mail dependency change"],"tags":["mail","multipart","body-part","messaging-exception"],"backgroundTag":"api-request-failed","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}