Skip to content

fix: handle undefined ephemeralMessage for iOS PTT audio messages#2552

Open
gabrielgz0 wants to merge 1 commit into
evolution-foundation:developfrom
gabrielgz0:fix/get-base64-ios-audio-ephemeral
Open

fix: handle undefined ephemeralMessage for iOS PTT audio messages#2552
gabrielgz0 wants to merge 1 commit into
evolution-foundation:developfrom
gabrielgz0:fix/get-base64-ios-audio-ephemeral

Conversation

@gabrielgz0
Copy link
Copy Markdown

@gabrielgz0 gabrielgz0 commented May 19, 2026

Summary

Fix a crash in POST /chat/getBase64FromMediaMessage/{instance} when processing iOS audio messages wrapped in ephemeralMessage without the expected .message property.

Problem

When an iPhone sends an audio message, the Baileys messages.upsert event delivers it wrapped in an ephemeralMessage container. The service iterates over known MessageSubtype values and unwraps them:

for (const subtype of MessageSubtype) {
  if (msg.message[subtype]) {
    msg.message = msg.message[subtype].message; // crash
  }
}

iOS ephemeral messages can have ephemeralMessage as a truthy object without a standard .message property inside. When that happens:

  1. msg.message = undefined (.message doesn't exist on the subtype)
  2. Next loop iteration tries msg.message[subtype] -> TypeError: Cannot read properties of undefined (reading 'ephemeralMessage')

This also crashes when msg.message itself is undefined (e.g., passing a message object without valid content).

Error response

{"status":400,"error":"Bad Request","response":{"message":["TypeError: Cannot read properties of undefined (reading 'ephemeralMessage')"]}}

Changes

File: src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

  • Guard against falsy msg.message -- returns "Message not found" instead of crashing
  • Safe optional chaining in subtype loop -- msg.message[subtype]?.message ensures unwrapping only happens when .message actually exists, preventing msg.message from being set to undefined
+ if (!msg.message) {
+   throw 'Message not found';
+ }
+
  for (const subtype of MessageSubtype) {
-   if (msg.message[subtype]) {
+   if (msg.message[subtype]?.message) {
      msg.message = msg.message[subtype].message;
    }
  }

Testing

Scenarios verified

Input Before After
ephemeralMessage sem .message TypeError crash "The message is not of the media type"
message: null TypeError crash "Message not found"
messageContextInfo apenas TypeError crash null (skip)
Objeto vazio / string TypeError crash "Message not found"
ephemeralMessage com audio valido works works
audioMessage direto (DB format) works works

Checks

  • Lint -- npm run lint:check clean
  • TypeScript -- tsc --noEmit clean
  • Pre-commit hooks passed

Closes #2550

Summary by Sourcery

Bug Fixes:

  • Prevent crashes when processing iOS WhatsApp audio messages wrapped in ephemeral containers without a nested message object by guarding against falsy msg.message and safely unwrapping subtypes.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 19, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds defensive checks and safer unwrapping for WhatsApp Baileys ephemeral audio messages to prevent crashes when msg.message or its subtype .message are missing, returning a controlled "Message not found" error instead.

File-Level Changes

Change Details Files
Add a defensive guard to ensure msg.message exists before attempting to unwrap message subtypes, returning a controlled error when missing.
  • Insert an early check that throws "Message not found" when the incoming message has a falsy message payload before subtype handling.
  • Ensure that invalid or empty message objects now produce a predictable error instead of a runtime TypeError.
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
Harden the subtype unwrapping loop to only unwrap when a nested .message actually exists on the subtype, avoiding assignment of undefined and subsequent crashes.
  • Update the subtype check in the loop to use optional chaining (msg.message[subtype]?.message) before unwrapping.
  • Prevent msg.message from being set to undefined when processing ephemeral messages that lack a .message property, eliminating the TypeError when accessing further subtypes.
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

Possibly linked issues

  • #unknown: PR adds guards and optional chaining to stop TypeError in getBase64FromMediaMessage for iOS ephemeral audio messages.

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

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The new if (!msg.message) check appears redundant with the existing if (!msg?.message) guard just above it; consider consolidating to a single null/undefined check to avoid duplication.
  • Since you're now depending on msg.message[subtype]?.message specifically, it might be safer to narrow the loop to only subtypes known to wrap a .message to avoid silently skipping other container shapes in the future.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `if (!msg.message)` check appears redundant with the existing `if (!msg?.message)` guard just above it; consider consolidating to a single null/undefined check to avoid duplication.
- Since you're now depending on `msg.message[subtype]?.message` specifically, it might be safer to narrow the loop to only subtypes known to wrap a `.message` to avoid silently skipping other container shapes in the future.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@gabrielgz0 gabrielgz0 force-pushed the fix/get-base64-ios-audio-ephemeral branch from c69d13d to 75506ca Compare May 19, 2026 22:30
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.

1 participant