onMessageSendHandler re-executes after PromptUser override for inline attachments (Desktop Only)

Maxime.L 20 Reputation points
2025-10-07T13:54:29.5966667+00:00

Context: The issue occurs in an Outlook Mail Compose Add-in using the onMessageSendHandler function (which handles the ItemSend event). The code is adapted from the official documentation: "Automatically check for an attachment before a message is sent".

The goal of the specific code block below is to prompt the user if they've mentioned sending a "picture" or "document" but have only included inline attachments.

Steps to Reproduce:

  1. Compose a new email in Outlook (New Outlook, Web, or Desktop).
  2. Include a term from the arrayOfTerms (e.g., "picture" or "document") in the email body.
  3. Include at least one inline image (e.g., paste an image from the clipboard). Ensure there are no external (non-inline) attachments.
  4. Click the Send button.
  5. The onMessageSendHandler function is triggered. In the getAttachmentsCallback function, the following block is executed because attachments exist but all are inline (the condition asyncResult.value[i].isInline == false is never met):
// Block executed when only inline attachments exist
event.completed({
  allowEvent: false,
  errorMessage:
    "Looks like the body of your message includes an image or an inline file. Would you like to attach a copy of it to the message?",
  errorMessageMarkdown:
    "Looks like the body of your message includes an image or an inline file. Would you like to attach a copy of it to the message?\n\n**Tip**: For guidance on how to attach a file, see [Attach files in Outlook](https://www.contoso.com/help/attach-files-in-outlook).",
  cancelLabel: "Attach a copy",
  commandId: "msgComposeOpenPaneButton",
  sendModeOverride: Office.MailboxEnums.SendModeOverride.PromptUser,
});
  1. A prompt dialog appears asking the user to confirm the send, with a "Send Anyway" button (due to sendModeOverride: PromptUser).
  2. The user clicks "Send Anyway".

Expected Behavior: The dialog closes and the email is sent successfully. The onMessageSendHandler function should not be re-executed.

Actual Behavior:

The dialog closes.

The onMessageSendHandler function is immediately triggered again.

The same prompt dialog reappears, asking the exact same question.

The user must click "Send Anyway" a second time for the email to finally be sent.

Relevant Code Snippet (getAttachmentsCallback):


function getAttachmentsCallback(asyncResult) {
  const event = asyncResult.asyncContext;
  if (asyncResult.value.length > 0) {
    for (let i = 0; i < asyncResult.value.length; i++) {
      if (asyncResult.value[i].isInline == false) {
        event.completed({ allowEvent: true });
        return;
      }
    }

    event.completed({
      allowEvent: false,
      errorMessage:
        "Looks like the body of your message includes an image or an inline file. Would you like to attach a copy of it to the message?",
      // TIP: In addition to the formatted message, it's recommended to also set a
      // plain text message in the errorMessage property for compatibility on
      // older versions of Outlook clients.
      errorMessageMarkdown:
        "Looks like the body of your message includes an image or an inline file. Would you like to attach a copy of it to the message?\n\n**Tip**: For guidance on how to attach a file, see [Attach files in Outlook](https://www.contoso.com/help/attach-files-in-outlook).",
      cancelLabel: "Attach a copy",
      commandId: "msgComposeOpenPaneButton",
      sendModeOverride: Office.MailboxEnums.SendModeOverride.PromptUser,
    });
  } else {
    event.completed({
      allowEvent: false,
      errorMessage: "Looks like you're forgetting to include an attachment.",
      // TIP: In addition to the formatted message, it's recommended to also set a
      // plain text message in the errorMessage property for compatibility on
      // older versions of Outlook clients.
      errorMessageMarkdown:
        "Looks like you're forgetting to include an attachment.\n\n**Tip**: For guidance on how to attach a file, see [Attach files in Outlook](https://www.contoso.com/help/attach-files-in-outlook).",
      cancelLabel: "Add an attachment",
      commandId: "msgComposeOpenPaneButton",
    });
  }
}

Environment

Host: Outlook (Desktop and WEB)

Office.js Version : 1 .0.37

Project Type : Office Add-in Task Pane project
Script Type : JavaScript
Manifest Type : Unified manifest for Microsoft 365

Microsoft 365 and Office | Development | Office JavaScript API
{count} votes

Answer accepted by question author
  1. Jack-Bu 4,590 Reputation points Microsoft External Staff Moderator
    2025-10-07T14:49:43.4266667+00:00

    Hello Maxime.L

    Thank you for reaching out to Microsoft Q&A forum regarding the issue with your Outlook Mail Compose Add-in, specifically the re-triggering of the onMessageSendHandler function in Outlook Desktop clients (both classic and New Outlook) when using the PromptUser send mode override for inline attachments. This behavior appears to be a client-specific handling in Outlook Desktop on Windows, where selecting "Send Anyway" in the prompt dialog causes an immediate retry of the send operation. This retry re-invokes the handler without changes to the message state, resulting in the prompt reappearing. In contrast, Outlook on the web (OWA) processes the override and sends the email without re-triggering the event.

    To confirm, this aligns with known differences in how desktop clients manage event retries and user overrides in Smart Alerts scenarios, though it's not documented as a bug.

    As a workaround, you can implement a timestamp-based check to detect and bypass the rapid re-trigger. This assumes the desktop retry occurs almost immediately (within approximately 2 seconds), while manual re-sends after user modifications would take longer. Here's how to apply it:

    1. Declare a global variable outside the function to track the last prompt timestamp, e.g.: let lastPromptTime = 0;
    2. In your getAttachmentsCallback function, after checking for non-inline attachments and before prompting for inline ones, add a check like this:
             // Check if this is a rapid re-trigger (likely from "Send Anyway" on desktop)
             const now = Date.now();
             if (now - lastPromptTime < 2000) { // Adjust threshold if needed (e.g., 1000-3000 ms)
               event.completed({ allowEvent: true });
               return;
             }
             // Set timestamp and prompt
             lastPromptTime = now;
      

    You can adjust the 2000 ms threshold based on your testing to balance catching auto-retries without interfering with quick manual actions. This approach should resolve the double-prompt issue on desktop without affecting OWA behavior.

    If this doesn't fully resolve it (e.g., if the re-trigger timing varies), consider setting the send mode to "promptUser" in your unified manifest's autoRunEvents.events.options.sendMode property instead of overriding it at runtime. Then, remove sendModeOverride from the code for the inline case (keeping it as a soft prompt with "Send Anyway"). If you need stricter blocking in the no-attachments branch, override to Block or SoftBlock there. This might avoid the retry behavior altogether, as manifest-level modes are handled more consistently by the client.

    I hope this information can clarify your concern. If you have any additional concern, feel free to comment below. I be more than happy to assist.  


    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".      

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread. 


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.