evolution-api icon indicating copy to clipboard operation
evolution-api copied to clipboard

fix: handle messageContextInfo in media upload to prevent MinIO errors

Open kay0ramon opened this issue 1 month ago โ€ข 4 comments

This PR fixes the Error on upload file to minio error that occurs when processing messages containing only messageContextInfo without actual media content.

Problem

When WhatsApp sends media messages (audio, video, images) with ephemeral/viewOnce wrappers, the message structure gets transformed during processing. After the MessageSubtype loop transformation, some messages end up containing only messageContextInfo metadata without the actual media binary data. The previous code would throw an error in this case, causing thousands of error logs like:

[ 'Error on upload file to minio', [ 'The message is messageContextInfo' ], undefined ]

Solution

  1. Changed throw 'The message is messageContextInfo' to return null in getBase64FromMediaMessage() function
  2. Added null checks before attempting MinIO upload in both received and sent message handlers
  3. Messages without valid media content are now gracefully skipped with a verbose log instead of throwing errors

Changes Made

  • getBase64FromMediaMessage(): Returns null instead of throwing when message contains only messageContextInfo
  • Received messages upload (line ~1285): Added if (!media) return check
  • Sent messages upload (line ~2322): Added if (!media) return check

๐Ÿ”— Related Issue

Closes #1026 Related: #1061, #1585, #1872

๐Ÿงช Type of Change

  • [x] ๐Ÿ› Bug fix (non-breaking change which fixes an issue)
  • [ ] โœจ New feature (non-breaking change which adds functionality)
  • [ ] ๐Ÿ’ฅ Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • [ ] ๐Ÿ“š Documentation update
  • [ ] ๐Ÿ”ง Refactoring (no functional changes)
  • [ ] โšก Performance improvement
  • [ ] ๐Ÿงน Code cleanup
  • [ ] ๐Ÿ”’ Security fix

๐Ÿงช Testing

  • [x] Manual testing completed
  • [x] Functionality verified in development environment
  • [x] No breaking changes introduced
  • [x] Tested with different connection types (if applicable)

Testing Details

  • Tested in production environment with high message volume
  • Verified that regular media messages (audio, video, images, documents) continue to upload correctly to MinIO
  • Confirmed that messages with only messageContextInfo are now skipped gracefully
  • Error logs reduced from 4,648+ occurrences to zero
  • No impact on message delivery or storage functionality

๐Ÿ“ธ Screenshots (if applicable)

Before (error logs): [ERROR] [ChannelStartupService] Error processing media message: [ERROR] [ChannelStartupService] The message is messageContextInfo [ 'Error on upload file to minio', [ 'The message is messageContextInfo' ], undefined ]

After (clean logs): [VERBOSE] [BaileysStartupService] Message contains only messageContextInfo, skipping media processing

โœ… Checklist

  • [x] My code follows the project's style guidelines
  • [x] I have performed a self-review of my code
  • [x] I have commented my code, particularly in hard-to-understand areas
  • [ ] I have made corresponding changes to the documentation
  • [x] My changes generate no new warnings
  • [x] I have manually tested my changes thoroughly
  • [x] I have verified the changes work with different scenarios
  • [x] Any dependent changes have been merged and published

๐Ÿ“ Additional Notes

Root Cause Analysis

The issue occurs due to the interaction between:

  1. Baileys 7.x message structure changes with LID/PN addressing
  2. MessageSubtype transformation that unwraps ephemeral/viewOnce messages
  3. hasValidMediaContent() check happening BEFORE the subtype transformation
  4. messageContextInfo check happening AFTER the transformation

This creates a race condition where a message passes the initial media check but fails after transformation.

Backward Compatibility

  • โœ… Messages with real media content continue working normally
  • โœ… MinIO uploads for valid media are unaffected
  • โœ… No changes to database schema or API contracts
  • โœ… Chatwoot integration (if used) has its own try/catch and will handle null gracefully

Summary by Sourcery

Gracefully skip WhatsApp messages that contain only messageContextInfo during media handling to avoid unnecessary MinIO upload errors and noisy logs.

Bug Fixes:

  • Prevent MinIO upload attempts for WhatsApp messages that contain only messageContextInfo metadata without actual media content, eliminating related runtime errors and log spam.

Enhancements:

  • Log verbose messages when media processing is skipped due to messageContextInfo-only payloads for both received and sent messages.

kay0ramon avatar Nov 28 '25 19:11 kay0ramon

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Handles WhatsApp messages that contain only messageContextInfo without media by treating them as non-media and short-circuiting MinIO upload, converting a previous throw into a null return and adding guard checks and verbose logs around media extraction and upload paths.

Sequence diagram for WhatsApp media upload with messageContextInfo handling

sequenceDiagram
  actor WhatsAppServer
  participant BaileysStartupService
  participant getBase64FromMediaMessage
  participant MinIO
  participant Logger

  WhatsAppServer ->> BaileysStartupService: onMediaMessage message
  BaileysStartupService ->> getBase64FromMediaMessage: getBase64FromMediaMessage message, isFromBaileys
  getBase64FromMediaMessage -->> BaileysStartupService: mediaOrNull

  alt mediaOrNull is null (messageContextInfo only)
    BaileysStartupService ->> Logger: verbose [No valid media to upload (messageContextInfo only), skipping MinIO]
    BaileysStartupService -->> WhatsAppServer: continue without MinIO upload
  else valid media object
    BaileysStartupService ->> MinIO: upload buffer, mediaType, fileName, size, mimetype
    MinIO -->> BaileysStartupService: uploadResult
    BaileysStartupService -->> WhatsAppServer: processing completed
  end

Flow diagram for getBase64FromMediaMessage messageContextInfo handling

flowchart TD
  A[Receive message in getBase64FromMediaMessage] --> B[Check if message contains messageContextInfo key]
  B -->|No| C[Proceed to media extraction]
  C --> D[Decode media binary data]
  D --> E[Build media object buffer, mediaType, fileName, size]
  E --> F[Return media object]

  B -->|Yes| G[Check if message has only messageContextInfo field]
  G -->|No| C
  G -->|Yes| H[Logger verbose Message contains only messageContextInfo, skipping media processing]
  H --> I[Return null to caller]

File-Level Changes

Change Details Files
Short-circuit MinIO upload when media extraction returns null for messageContextInfo-only messages.
  • After getBase64FromMediaMessage in the inbound media handling flow, added a null/falsey check on the media result and early return with a verbose log when there is no valid media.
  • After getBase64FromMediaMessage in the outbound media handling flow, added a null/falsey check on the media result and early return with a verbose log when there is no valid media.
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
Treat messageContextInfo-only messages as non-media by returning null instead of throwing.
  • In getBase64FromMediaMessage, detect messages where message.message consists only of messageContextInfo and replace the thrown string error with a verbose log and a null return value so callers can handle this case gracefully.
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

Assessment against linked issues

Issue Objective Addressed Explanation
https://github.com/EvolutionAPI/evolution-api/issues/1026 Fix the MinIO upload errors (including TypeError/ERR_INVALID_ARG_TYPE) that occur when processing WhatsApp media messages which contain only messageContextInfo and no actual media content. โœ…
https://github.com/EvolutionAPI/evolution-api/issues/1026 Ensure WhatsApp media messages (e.g., images) are processed without crashing so they can be correctly handled by downstream integrations like Chatwoot instead of failing during upload. โœ…

Possibly linked issues

  • #0: PR changes MinIO media handling for messageContextInfo-only messages, addressing the audio upload errors seen in the issue.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an issue from a review comment by replying to it. You can also reply to a review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull request title to generate a title at any time. You can also comment @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in the pull request body to generate a PR summary at any time exactly where you want it. You can also comment @sourcery-ai summary on the pull request to (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the pull request to resolve all Sourcery comments. Useful if you've already addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull request to dismiss all existing Sourcery reviews. Especially useful if you want to start fresh with a new review - don't forget to comment @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

  • Contact our support team for questions or feedback.
  • Visit our documentation for detailed guides and information.
  • Keep in touch with the Sourcery team by following us on X/Twitter, LinkedIn or GitHub.

sourcery-ai[bot] avatar Nov 28 '25 19:11 sourcery-ai[bot]

Resolveu aqui, muito obrigado!

allefrodrigo avatar Nov 28 '25 19:11 allefrodrigo

Boa! Deu certo! Obrigado!!

wagnerfnds avatar Nov 28 '25 19:11 wagnerfnds

Issue scaled significantly. Apparently, not only with viewOnce chats anymore.

We need to handle in a more robust way, because most of the times, a standalone call to /getBase64FromMediaMessage works to get the base64 and display media properly on Evolution Manager or handle it for S3/MinIO..

Anyone have managed to get around this?

itsfabioroma avatar Dec 01 '25 02:12 itsfabioroma

Please, fix the lint with npm run lint

DavidsonGomes avatar Dec 05 '25 13:12 DavidsonGomes