Skip to content

Fix multi-attachment comments rendering as separate messages#82533

Closed
nicepopo86-lang wants to merge 1 commit intoExpensify:mainfrom
nicepopo86-lang:fix/76269-attachment-single-message
Closed

Fix multi-attachment comments rendering as separate messages#82533
nicepopo86-lang wants to merge 1 commit intoExpensify:mainfrom
nicepopo86-lang:fix/76269-attachment-single-message

Conversation

@nicepopo86-lang
Copy link

@nicepopo86-lang nicepopo86-lang commented Feb 16, 2026

Details

$ #76269.

When sending multiple attachments (with or without text), the client currently loops and sends one request per file. That creates multiple report actions, so the conversation shows separate messages even though the composer preview shows a single grouped message.

This PR keeps changes scoped by:

  • sending selected attachments in one addActions() call
  • allowing file payloads to be FileObject | FileObject[]
  • building optimistic comment HTML from all selected attachments in a single report action
  • updating request payload builders (prepareRequestPayload web/native) to append array values (including file) into FormData
  • updating ReportTest expectations for multi-attachment flows

Testing

I could not run Jest in this environment because the repo requires Node 20.19.5 and this runner has Node 24.13.0 (engine mismatch).

@nicepopo86-lang nicepopo86-lang requested review from a team as code owners February 16, 2026 03:23
@melvin-bot melvin-bot bot requested review from heyjennahay and removed request for a team February 16, 2026 03:23
@github-actions
Copy link
Contributor


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


nicepopo86-lang seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@melvin-bot melvin-bot bot requested a review from youssef-lr February 16, 2026 03:23
@melvin-bot
Copy link

melvin-bot bot commented Feb 16, 2026

@youssef-lr Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@melvin-bot melvin-bot bot removed the request for review from a team February 16, 2026 03:23
addActions({report, notifyReportID, ancestors, timezoneParam: timezone, currentUserAccountID, text: '', file: attachments?.at(i), isInSidePanel});
}
// Send single or multiple attachments in one action
addActions({report, notifyReportID, ancestors, timezoneParam: timezone, currentUserAccountID, text, file: attachments, isInSidePanel});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ CONSISTENCY-6 (docs)

Bug: addActions is not updated to handle FileObject[] but now receives it.

The addActions function (lines 612-806) uses truthiness checks on file throughout:

  • if (text && \!file) (line 622) — an empty array [] is truthy, so this branch is skipped even when there are no files
  • if (file) (line 628) — truthy for [], so it would try to buildOptimisticAddCommentReportAction with an empty array
  • if (text && file) (line 636) — same issue, sets commandName = ADD_TEXT_AND_ATTACHMENT even for empty arrays
  • file ? ternaries (lines 688, 692) — would select attachment paths even when there are no actual files

Since attachments from addAttachmentWithComment is typed as FileObject | FileObject[], and the caller can pass an array, addActions needs to be updated to handle arrays properly. At minimum, the truthiness checks should use something like:

const hasFile = Array.isArray(file) ? file.length > 0 : \!\!file;

And replace all file / \!file checks with hasFile / \!hasFile.


Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e61e1aa40b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +17 to +22
if (Array.isArray(value)) {
value.forEach((singleValue) => {
validateFormDataParameter(command, key, singleValue);
formData.append(key, singleValue as string | Blob);
});
continue;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve list parameter wire format for non-file arrays

The new generic Array.isArray(value) branch changes every array field from a single form value to repeated keys, not just file. That silently alters the payload format for existing *IDList/*List write commands that currently pass arrays through API.write, while other request builders in this repo still explicitly serialize list params as comma-delimited strings (for example exportSearchItemsToCSV and exportReportToCSV). This mismatch can cause bulk operations to run on an incomplete/incorrect ID set when the backend expects the legacy comma-separated form.

Useful? React with 👍 / 👎.

@youssef-lr
Copy link
Contributor

@nicepopo86-lang please familiarize yourself with out contribution guidelines found here. You may not raise a PR until a C+ and an internal engineer has assigned you.

@youssef-lr youssef-lr closed this Feb 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants